diff options
author | Valentin Bartenev <vbart@nginx.com> | 2015-03-14 17:37:25 +0300 |
---|---|---|
committer | Valentin Bartenev <vbart@nginx.com> | 2015-03-14 17:37:25 +0300 |
commit | a7ad493aa67c5f5204afbe50a42108d9e5b07c31 (patch) | |
tree | 0c2277cd365146cfcbfc28ed8298620bcc7bf5cb /src/os/unix | |
parent | 547c8f601f80c4dbdd16562fec3cf947581b300a (diff) | |
download | nginx-a7ad493aa67c5f5204afbe50a42108d9e5b07c31.tar.gz nginx-a7ad493aa67c5f5204afbe50a42108d9e5b07c31.zip |
Added support for offloading read() in thread pools.
Diffstat (limited to 'src/os/unix')
-rw-r--r-- | src/os/unix/ngx_files.c | 109 | ||||
-rw-r--r-- | src/os/unix/ngx_files.h | 5 |
2 files changed, 114 insertions, 0 deletions
diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c index c3ae47fdb..2a3ed2f26 100644 --- a/src/os/unix/ngx_files.c +++ b/src/os/unix/ngx_files.c @@ -9,6 +9,12 @@ #include <ngx_core.h> +#if (NGX_THREADS) +#include <ngx_thread_pool.h> +static void ngx_thread_read_handler(void *data, ngx_log_t *log); +#endif + + #if (NGX_HAVE_FILE_AIO) ngx_uint_t ngx_file_aio = 1; @@ -64,6 +70,109 @@ ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) } +#if (NGX_THREADS) + +typedef struct { + ngx_fd_t fd; + u_char *buf; + size_t size; + off_t offset; + + size_t read; + ngx_err_t err; +} ngx_thread_read_ctx_t; + + +ssize_t +ngx_thread_read(ngx_thread_task_t **taskp, ngx_file_t *file, u_char *buf, + size_t size, off_t offset, ngx_pool_t *pool) +{ + ngx_thread_task_t *task; + ngx_thread_read_ctx_t *ctx; + + ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0, + "thread read: %d, %p, %uz, %O", + file->fd, buf, size, offset); + + task = *taskp; + + if (task == NULL) { + task = ngx_thread_task_alloc(pool, sizeof(ngx_thread_read_ctx_t)); + if (task == NULL) { + return NGX_ERROR; + } + + task->handler = ngx_thread_read_handler; + + *taskp = task; + } + + ctx = task->ctx; + + if (task->event.complete) { + task->event.complete = 0; + + if (ctx->err) { + ngx_log_error(NGX_LOG_CRIT, file->log, ctx->err, + "pread() \"%s\" failed", file->name.data); + return NGX_ERROR; + } + + return ctx->read; + } + + ctx->fd = file->fd; + ctx->buf = buf; + ctx->size = size; + ctx->offset = offset; + + if (file->thread_handler(task, file) != NGX_OK) { + return NGX_ERROR; + } + + return NGX_AGAIN; +} + + +#if (NGX_HAVE_PREAD) + +static void +ngx_thread_read_handler(void *data, ngx_log_t *log) +{ + ngx_thread_read_ctx_t *ctx = data; + + ssize_t n; + + ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "thread read handler"); + + n = pread(ctx->fd, ctx->buf, ctx->size, ctx->offset); + + if (n == -1) { + ctx->err = ngx_errno; + + } else { + ctx->read = n; + ctx->err = 0; + } + +#if 0 + ngx_time_update(); +#endif + + ngx_log_debug4(NGX_LOG_DEBUG_CORE, log, 0, + "pread: %z (err: %i) of %uz @%O", + n, ctx->err, ctx->size, ctx->offset); +} + +#else + +#error pread() is required! + +#endif + +#endif /* NGX_THREADS */ + + ssize_t ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) { diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h index a046ee756..b6990bc6e 100644 --- a/src/os/unix/ngx_files.h +++ b/src/os/unix/ngx_files.h @@ -383,5 +383,10 @@ extern ngx_uint_t ngx_file_aio; #endif +#if (NGX_THREADS) +ssize_t ngx_thread_read(ngx_thread_task_t **taskp, ngx_file_t *file, + u_char *buf, size_t size, off_t offset, ngx_pool_t *pool); +#endif + #endif /* _NGX_FILES_H_INCLUDED_ */ |