fix extension
[nginx.git] / nginx / src / event / modules / ngx_aio_module.c
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 #include <ngx_aio.h>
11
12 #if (NGX_HAVE_KQUEUE)
13 #include <ngx_kqueue_module.h>
14 #endif
15
16
17 static ngx_int_t ngx_aio_init(ngx_cycle_t *cycle, ngx_msec_t timer);
18 static void ngx_aio_done(ngx_cycle_t *cycle);
19 static ngx_int_t ngx_aio_add_event(ngx_event_t *ev, ngx_int_t event,
20     ngx_uint_t flags);
21 static ngx_int_t ngx_aio_del_event(ngx_event_t *ev, ngx_int_t event,
22     ngx_uint_t flags);
23 static ngx_int_t ngx_aio_del_connection(ngx_connection_t *c, ngx_uint_t flags);
24 static ngx_int_t ngx_aio_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
25     ngx_uint_t flags);
26
27
28 ngx_os_io_t ngx_os_aio = {
29     ngx_aio_read,
30     ngx_aio_read_chain,
31     NULL,
32     ngx_aio_write,
33     ngx_aio_write_chain,
34     0
35 };
36
37
38 static ngx_str_t      aio_name = ngx_string("aio");
39
40 ngx_event_module_t  ngx_aio_module_ctx = {
41     &aio_name,
42     NULL,                                  /* create configuration */
43     NULL,                                  /* init configuration */
44
45     {
46         ngx_aio_add_event,                 /* add an event */
47         ngx_aio_del_event,                 /* delete an event */
48         NULL,                              /* enable an event */
49         NULL,                              /* disable an event */
50         NULL,                              /* add an connection */
51         ngx_aio_del_connection,            /* delete an connection */
52         NULL,                              /* process the changes */
53         ngx_aio_process_events,            /* process the events */
54         ngx_aio_init,                      /* init the events */
55         ngx_aio_done                       /* done the events */
56     }
57
58 };
59
60 ngx_module_t  ngx_aio_module = {
61     NGX_MODULE_V1,
62     &ngx_aio_module_ctx,                   /* module context */
63     NULL,                                  /* module directives */
64     NGX_EVENT_MODULE,                      /* module type */
65     NULL,                                  /* init master */
66     NULL,                                  /* init module */
67     NULL,                                  /* init process */
68     NULL,                                  /* init thread */
69     NULL,                                  /* exit thread */
70     NULL,                                  /* exit process */
71     NULL,                                  /* exit master */
72     NGX_MODULE_V1_PADDING
73 };
74
75
76
77 #if (NGX_HAVE_KQUEUE)
78
79 static ngx_int_t
80 ngx_aio_init(ngx_cycle_t *cycle, ngx_msec_t timer)
81 {
82     if (ngx_kqueue_module_ctx.actions.init(cycle, timer) == NGX_ERROR) {
83         return NGX_ERROR;
84     }
85
86     ngx_io = ngx_os_aio;
87
88     ngx_event_flags = NGX_USE_AIO_EVENT;
89     ngx_event_actions = ngx_aio_module_ctx.actions;
90
91
92     return NGX_OK;
93 }
94
95
96 static void
97 ngx_aio_done(ngx_cycle_t *cycle)
98 {
99     ngx_kqueue_module_ctx.actions.done(cycle);
100 }
101
102
103 /* the event adding and deleting are needed for the listening sockets */
104
105 static ngx_int_t
106 ngx_aio_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
107 {
108     return ngx_kqueue_module_ctx.actions.add(ev, event, flags);
109 }
110
111
112 static ngx_int_t
113 ngx_aio_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
114 {
115     return ngx_kqueue_module_ctx.actions.del(ev, event, flags);
116 }
117
118
119 static ngx_int_t
120 ngx_aio_del_connection(ngx_connection_t *c, ngx_uint_t flags)
121 {
122     int  rc;
123
124     if (c->read->active == 0 && c->write->active == 0) {
125         return NGX_OK;
126     }
127
128     if (flags & NGX_CLOSE_EVENT) {
129         return NGX_OK;
130     }
131
132     rc = aio_cancel(c->fd, NULL);
133
134     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "aio_cancel: %d", rc);
135
136     if (rc == AIO_CANCELED) {
137         c->read->active = c->write->active = 0;
138         return NGX_OK;
139     }
140
141     if (rc == AIO_ALLDONE) {
142         c->read->active = c->write->active = 0;
143         ngx_log_error(NGX_LOG_ALERT, c->log, 0,
144                       "aio_cancel() returned AIO_ALLDONE");
145         return NGX_OK;
146     }
147
148     if (rc == -1) {
149         ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
150                       "aio_cancel() failed");
151         return NGX_ERROR;
152     }
153
154     if (rc == AIO_NOTCANCELED) {
155         ngx_log_error(NGX_LOG_ALERT, c->log, 0,
156                       "aio_cancel() returned AIO_NOTCANCELED");
157
158         return NGX_ERROR;
159     }
160
161     return NGX_OK;
162 }
163
164
165 static ngx_int_t
166 ngx_aio_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
167 {
168     return ngx_kqueue_module_ctx.actions.process_events(cycle, timer, flags);
169 }
170
171 #endif /* NGX_HAVE_KQUEUE */