~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Nginx/os/unix/ngx_linux_aio_read.c

Version: ~ [ nginx-0.8.20 ] ~ [ nginx-0.7.62 ] ~ [ nginx-0.6.39 ] ~

  1 
  2 /*
  3  * Copyright (C) Igor Sysoev
  4  */
  5 
  6 
  7 #include <ngx_config.h>
  8 #include <ngx_core.h>
  9 #include <ngx_event.h>
 10 
 11 
 12 extern int            ngx_eventfd;
 13 extern aio_context_t  ngx_aio_ctx;
 14 
 15 
 16 static void ngx_file_aio_event_handler(ngx_event_t *ev);
 17 
 18 
 19 static long
 20 io_submit(aio_context_t ctx, long n, struct iocb **paiocb)
 21 {
 22     return syscall(SYS_io_submit, ctx, n, paiocb);
 23 }
 24 
 25 
 26 ssize_t
 27 ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset,
 28     ngx_pool_t *pool)
 29 {
 30     long                n;
 31     struct iocb        *piocb[1];
 32     ngx_event_t        *ev;
 33     ngx_event_aio_t    *aio;
 34     static ngx_uint_t   enosys = 0;
 35 
 36     if (enosys) {
 37         return ngx_read_file(file, buf, size, offset);
 38     }
 39 
 40     aio = file->aio;
 41 
 42     if (aio == NULL) {
 43         aio = ngx_pcalloc(pool, sizeof(ngx_event_aio_t));
 44         if (aio == NULL) {
 45             return NGX_ERROR;
 46         }
 47 
 48         aio->file = file;
 49         aio->fd = file->fd;
 50         aio->event.data = aio;
 51         aio->event.ready = 1;
 52         aio->event.log = file->log;
 53         file->aio = aio;
 54     }
 55 
 56     ev = &aio->event;
 57 
 58     if (!ev->ready) {
 59         ngx_log_error(NGX_LOG_ALERT, file->log, 0,
 60                       "second aio post for \"%V\"", &file->name);
 61         return NGX_AGAIN;
 62     }
 63 
 64     ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
 65                    "aio complete:%d @%O:%z %V",
 66                    ev->complete, offset, size, &file->name);
 67 
 68     if (ev->complete) {
 69         ev->active = 0;
 70         ev->complete = 0;
 71 
 72         if (aio->res >= 0) {
 73             ngx_set_errno(0);
 74             return aio->res;
 75         }
 76 
 77         ngx_set_errno(-aio->res);
 78         return NGX_ERROR;
 79     }
 80 
 81     ngx_memzero(&aio->aiocb, sizeof(struct iocb));
 82 
 83     aio->aiocb.aio_data = (uint64_t) (uintptr_t) ev;
 84     aio->aiocb.aio_lio_opcode = IOCB_CMD_PREAD;
 85     aio->aiocb.aio_fildes = file->fd;
 86     aio->aiocb.aio_buf = (uint64_t) (uintptr_t) buf;
 87     aio->aiocb.aio_nbytes = size;
 88     aio->aiocb.aio_offset = offset;
 89     aio->aiocb.aio_flags = IOCB_FLAG_RESFD;
 90     aio->aiocb.aio_resfd = ngx_eventfd;
 91 
 92     ev->handler = ngx_file_aio_event_handler;
 93 
 94     piocb[0] = &aio->aiocb;
 95 
 96     n = io_submit(ngx_aio_ctx, 1, piocb);
 97 
 98     if (n == 1) {
 99         return NGX_AGAIN;
100     }
101 
102     n = -n;
103 
104     if (n == NGX_EAGAIN) {
105         return ngx_read_file(file, buf, size, offset);
106     }
107 
108     ngx_log_error(NGX_LOG_CRIT, file->log, n,
109                   "io_submit(\"%V\") failed", &file->name);
110 
111     if (n == NGX_ENOSYS) {
112         enosys = 1;
113         return ngx_read_file(file, buf, size, offset);
114     }
115 
116     return NGX_ERROR;
117 }
118 
119 
120 static void
121 ngx_file_aio_event_handler(ngx_event_t *ev)
122 {
123     ngx_event_aio_t  *aio;
124 
125     aio = ev->data;
126 
127     ngx_log_debug2(NGX_LOG_DEBUG_CORE, ev->log, 0,
128                    "aio event handler fd:%d %V", aio->fd, &aio->file->name);
129 
130     aio->handler(ev);
131 }
132 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.