comparison src/os/unix/ngx_files.c @ 6022:1fdba317ee6d

Added support for offloading read() in thread pools.
author Valentin Bartenev <vbart@nginx.com>
date Sat, 14 Mar 2015 17:37:25 +0300
parents 1e2d5d3f9f6b
children 6fce16b1fc10
comparison
equal deleted inserted replaced
6021:117c77b22db1 6022:1fdba317ee6d
7 7
8 #include <ngx_config.h> 8 #include <ngx_config.h>
9 #include <ngx_core.h> 9 #include <ngx_core.h>
10 10
11 11
12 #if (NGX_THREADS)
13 #include <ngx_thread_pool.h>
14 static void ngx_thread_read_handler(void *data, ngx_log_t *log);
15 #endif
16
17
12 #if (NGX_HAVE_FILE_AIO) 18 #if (NGX_HAVE_FILE_AIO)
13 19
14 ngx_uint_t ngx_file_aio = 1; 20 ngx_uint_t ngx_file_aio = 1;
15 21
16 #endif 22 #endif
60 66
61 file->offset += n; 67 file->offset += n;
62 68
63 return n; 69 return n;
64 } 70 }
71
72
73 #if (NGX_THREADS)
74
75 typedef struct {
76 ngx_fd_t fd;
77 u_char *buf;
78 size_t size;
79 off_t offset;
80
81 size_t read;
82 ngx_err_t err;
83 } ngx_thread_read_ctx_t;
84
85
86 ssize_t
87 ngx_thread_read(ngx_thread_task_t **taskp, ngx_file_t *file, u_char *buf,
88 size_t size, off_t offset, ngx_pool_t *pool)
89 {
90 ngx_thread_task_t *task;
91 ngx_thread_read_ctx_t *ctx;
92
93 ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
94 "thread read: %d, %p, %uz, %O",
95 file->fd, buf, size, offset);
96
97 task = *taskp;
98
99 if (task == NULL) {
100 task = ngx_thread_task_alloc(pool, sizeof(ngx_thread_read_ctx_t));
101 if (task == NULL) {
102 return NGX_ERROR;
103 }
104
105 task->handler = ngx_thread_read_handler;
106
107 *taskp = task;
108 }
109
110 ctx = task->ctx;
111
112 if (task->event.complete) {
113 task->event.complete = 0;
114
115 if (ctx->err) {
116 ngx_log_error(NGX_LOG_CRIT, file->log, ctx->err,
117 "pread() \"%s\" failed", file->name.data);
118 return NGX_ERROR;
119 }
120
121 return ctx->read;
122 }
123
124 ctx->fd = file->fd;
125 ctx->buf = buf;
126 ctx->size = size;
127 ctx->offset = offset;
128
129 if (file->thread_handler(task, file) != NGX_OK) {
130 return NGX_ERROR;
131 }
132
133 return NGX_AGAIN;
134 }
135
136
137 #if (NGX_HAVE_PREAD)
138
139 static void
140 ngx_thread_read_handler(void *data, ngx_log_t *log)
141 {
142 ngx_thread_read_ctx_t *ctx = data;
143
144 ssize_t n;
145
146 ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "thread read handler");
147
148 n = pread(ctx->fd, ctx->buf, ctx->size, ctx->offset);
149
150 if (n == -1) {
151 ctx->err = ngx_errno;
152
153 } else {
154 ctx->read = n;
155 ctx->err = 0;
156 }
157
158 #if 0
159 ngx_time_update();
160 #endif
161
162 ngx_log_debug4(NGX_LOG_DEBUG_CORE, log, 0,
163 "pread: %z (err: %i) of %uz @%O",
164 n, ctx->err, ctx->size, ctx->offset);
165 }
166
167 #else
168
169 #error pread() is required!
170
171 #endif
172
173 #endif /* NGX_THREADS */
65 174
66 175
67 ssize_t 176 ssize_t
68 ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) 177 ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
69 { 178 {