blob: 4561cf4bfab9e93998004a05cf94b511201bb69a [file] [log] [blame]
Igor Sysoev73009772003-02-06 17:21:13 +00001
2#include <ngx_config.h>
3#include <ngx_core.h>
4#include <ngx_errno.h>
5#include <ngx_log.h>
6#include <ngx_recv.h>
7#include <ngx_connection.h>
8#include <ngx_event.h>
9
10#if (HAVE_KQUEUE)
11#include <ngx_kqueue_module.h>
12#endif
13
14
15/*
16 The data is ready - 3 syscalls:
17 aio_read(), aio_error(), aio_return()
18 The data is not ready - 4 (kqueue) or 5 syscalls:
19 aio_read(), aio_error(), notifiction,
20 aio_error(), aio_return()
21 aio_cancel(), aio_error()
22*/
23
24ssize_t ngx_event_aio_read(ngx_connection_t *c, char *buf, size_t size)
25{
26 int rc, first, canceled;
27 ngx_event_t *ev;
28
29 ev = c->read;
30
31 canceled = 0;
32
33 if (ev->timedout) {
34 ngx_set_socket_errno(NGX_ETIMEDOUT);
35 ngx_log_error(NGX_LOG_ERR, ev->log, 0, "aio_read() timed out");
36
37 rc = aio_cancel(c->fd, &ev->aiocb);
38 if (rc == -1) {
39 ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno,
40 "aio_cancel() failed");
41 return NGX_ERROR;
42 }
43
44 ngx_log_debug(ev->log, "aio_cancel: %d" _ rc);
45
46 canceled = 1;
47
48 ev->ready = 1;
49 }
50
51 first = 0;
52
53 if (!ev->ready) {
54 ngx_memzero(&ev->aiocb, sizeof(struct aiocb));
55
56 ev->aiocb.aio_fildes = c->fd;
57 ev->aiocb.aio_buf = buf;
58 ev->aiocb.aio_nbytes = size;
59
60#if (HAVE_KQUEUE)
61 ev->aiocb.aio_sigevent.sigev_notify_kqueue = kq;
62 ev->aiocb.aio_sigevent.sigev_notify = SIGEV_KEVENT;
63 ev->aiocb.aio_sigevent.sigev_value.sigval_ptr = ev;
64#endif
65
66 if (aio_read(&ev->aiocb) == -1) {
67 ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno,
68 "aio_read() failed");
69 return NGX_ERROR;
70 }
71
72 ngx_log_debug(ev->log, "aio_read: OK");
73
74 ev->active = 1;
75 first = 1;
76 }
77
78 ev->ready = 0;
79
80 rc = aio_error(&ev->aiocb);
81 if (rc == -1) {
82 ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno, "aio_error() failed");
83 return NGX_ERROR;
84 }
85
86 if (rc != 0) {
87 if (rc == NGX_EINPROGRESS) {
88 if (!first) {
89 ngx_log_error(NGX_LOG_CRIT, ev->log, rc,
90 "aio_read() still in progress");
91 }
92 return NGX_AGAIN;
93 }
94
95 if (rc == NGX_ECANCELED && canceled) {
96 return NGX_ERROR;
97 }
98
99 ngx_log_error(NGX_LOG_CRIT, ev->log, rc, "aio_read() failed");
100 return NGX_ERROR;
101 }
102
103 rc = aio_return(&ev->aiocb);
104 if (rc == -1) {
105 ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno, "aio_return() failed");
106
107 return NGX_ERROR;
108 }
109
110 ngx_log_debug(ev->log, "aio_read: %d" _ rc);
111
112 return rc;
113}