1e18a033bSKonstantin Ananyev
2e18a033bSKonstantin Ananyev/*
3e18a033bSKonstantin Ananyev * Copyright (C) Igor Sysoev
4e18a033bSKonstantin Ananyev * Copyright (C) Nginx, Inc.
5e18a033bSKonstantin Ananyev */
6e18a033bSKonstantin Ananyev
7e18a033bSKonstantin Ananyev
8e18a033bSKonstantin Ananyev#include <ngx_config.h>
9e18a033bSKonstantin Ananyev#include <ngx_core.h>
10e18a033bSKonstantin Ananyev#include <ngx_event.h>
11e18a033bSKonstantin Ananyev#include <ngx_iocp_module.h>
12e18a033bSKonstantin Ananyev
13e18a033bSKonstantin Ananyev
14e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_iocp_init(ngx_cycle_t *cycle, ngx_msec_t timer);
15e18a033bSKonstantin Ananyevstatic ngx_thread_value_t __stdcall ngx_iocp_timer(void *data);
16e18a033bSKonstantin Ananyevstatic void ngx_iocp_done(ngx_cycle_t *cycle);
17e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_iocp_add_event(ngx_event_t *ev, ngx_int_t event,
18e18a033bSKonstantin Ananyev    ngx_uint_t key);
19e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_iocp_del_connection(ngx_connection_t *c, ngx_uint_t flags);
20e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_iocp_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
21e18a033bSKonstantin Ananyev    ngx_uint_t flags);
22e18a033bSKonstantin Ananyevstatic void *ngx_iocp_create_conf(ngx_cycle_t *cycle);
23e18a033bSKonstantin Ananyevstatic char *ngx_iocp_init_conf(ngx_cycle_t *cycle, void *conf);
24e18a033bSKonstantin Ananyev
25e18a033bSKonstantin Ananyev
26e18a033bSKonstantin Ananyevstatic ngx_str_t      iocp_name = ngx_string("iocp");
27e18a033bSKonstantin Ananyev
28e18a033bSKonstantin Ananyevstatic ngx_command_t  ngx_iocp_commands[] = {
29e18a033bSKonstantin Ananyev
30e18a033bSKonstantin Ananyev    { ngx_string("iocp_threads"),
31e18a033bSKonstantin Ananyev      NGX_EVENT_CONF|NGX_CONF_TAKE1,
32e18a033bSKonstantin Ananyev      ngx_conf_set_num_slot,
33e18a033bSKonstantin Ananyev      0,
34e18a033bSKonstantin Ananyev      offsetof(ngx_iocp_conf_t, threads),
35e18a033bSKonstantin Ananyev      NULL },
36e18a033bSKonstantin Ananyev
37e18a033bSKonstantin Ananyev    { ngx_string("post_acceptex"),
38e18a033bSKonstantin Ananyev      NGX_EVENT_CONF|NGX_CONF_TAKE1,
39e18a033bSKonstantin Ananyev      ngx_conf_set_num_slot,
40e18a033bSKonstantin Ananyev      0,
41e18a033bSKonstantin Ananyev      offsetof(ngx_iocp_conf_t, post_acceptex),
42e18a033bSKonstantin Ananyev      NULL },
43e18a033bSKonstantin Ananyev
44e18a033bSKonstantin Ananyev    { ngx_string("acceptex_read"),
45e18a033bSKonstantin Ananyev      NGX_EVENT_CONF|NGX_CONF_FLAG,
46e18a033bSKonstantin Ananyev      ngx_conf_set_flag_slot,
47e18a033bSKonstantin Ananyev      0,
48e18a033bSKonstantin Ananyev      offsetof(ngx_iocp_conf_t, acceptex_read),
49e18a033bSKonstantin Ananyev      NULL },
50e18a033bSKonstantin Ananyev
51e18a033bSKonstantin Ananyev      ngx_null_command
52e18a033bSKonstantin Ananyev};
53e18a033bSKonstantin Ananyev
54e18a033bSKonstantin Ananyev
55e18a033bSKonstantin Ananyevstatic ngx_event_module_t  ngx_iocp_module_ctx = {
56e18a033bSKonstantin Ananyev    &iocp_name,
57e18a033bSKonstantin Ananyev    ngx_iocp_create_conf,                  /* create configuration */
58e18a033bSKonstantin Ananyev    ngx_iocp_init_conf,                    /* init configuration */
59e18a033bSKonstantin Ananyev
60e18a033bSKonstantin Ananyev    {
61e18a033bSKonstantin Ananyev        ngx_iocp_add_event,                /* add an event */
62e18a033bSKonstantin Ananyev        NULL,                              /* delete an event */
63e18a033bSKonstantin Ananyev        NULL,                              /* enable an event */
64e18a033bSKonstantin Ananyev        NULL,                              /* disable an event */
65e18a033bSKonstantin Ananyev        NULL,                              /* add an connection */
66e18a033bSKonstantin Ananyev        ngx_iocp_del_connection,           /* delete an connection */
67e18a033bSKonstantin Ananyev        NULL,                              /* trigger a notify */
68e18a033bSKonstantin Ananyev        ngx_iocp_process_events,           /* process the events */
69e18a033bSKonstantin Ananyev        ngx_iocp_init,                     /* init the events */
70e18a033bSKonstantin Ananyev        ngx_iocp_done                      /* done the events */
71e18a033bSKonstantin Ananyev    }
72e18a033bSKonstantin Ananyev
73e18a033bSKonstantin Ananyev};
74e18a033bSKonstantin Ananyev
75e18a033bSKonstantin Ananyevngx_module_t  ngx_iocp_module = {
76e18a033bSKonstantin Ananyev    NGX_MODULE_V1,
77e18a033bSKonstantin Ananyev    &ngx_iocp_module_ctx,                  /* module context */
78e18a033bSKonstantin Ananyev    ngx_iocp_commands,                     /* module directives */
79e18a033bSKonstantin Ananyev    NGX_EVENT_MODULE,                      /* module type */
80e18a033bSKonstantin Ananyev    NULL,                                  /* init master */
81e18a033bSKonstantin Ananyev    NULL,                                  /* init module */
82e18a033bSKonstantin Ananyev    NULL,                                  /* init process */
83e18a033bSKonstantin Ananyev    NULL,                                  /* init thread */
84e18a033bSKonstantin Ananyev    NULL,                                  /* exit thread */
85e18a033bSKonstantin Ananyev    NULL,                                  /* exit process */
86e18a033bSKonstantin Ananyev    NULL,                                  /* exit master */
87e18a033bSKonstantin Ananyev    NGX_MODULE_V1_PADDING
88e18a033bSKonstantin Ananyev};
89e18a033bSKonstantin Ananyev
90e18a033bSKonstantin Ananyev
91e18a033bSKonstantin Ananyevngx_os_io_t ngx_iocp_io = {
92e18a033bSKonstantin Ananyev    ngx_overlapped_wsarecv,
93e18a033bSKonstantin Ananyev    NULL,
94e18a033bSKonstantin Ananyev    ngx_udp_overlapped_wsarecv,
95e18a033bSKonstantin Ananyev    NULL,
96e18a033bSKonstantin Ananyev    NULL,
97e18a033bSKonstantin Ananyev    NULL,
98e18a033bSKonstantin Ananyev    ngx_overlapped_wsasend_chain,
99e18a033bSKonstantin Ananyev    0
100e18a033bSKonstantin Ananyev};
101e18a033bSKonstantin Ananyev
102e18a033bSKonstantin Ananyev
103e18a033bSKonstantin Ananyevstatic HANDLE      iocp;
104e18a033bSKonstantin Ananyevstatic ngx_tid_t   timer_thread;
105e18a033bSKonstantin Ananyevstatic ngx_msec_t  msec;
106e18a033bSKonstantin Ananyev
107e18a033bSKonstantin Ananyev
108e18a033bSKonstantin Ananyevstatic ngx_int_t
109e18a033bSKonstantin Ananyevngx_iocp_init(ngx_cycle_t *cycle, ngx_msec_t timer)
110e18a033bSKonstantin Ananyev{
111e18a033bSKonstantin Ananyev    ngx_iocp_conf_t  *cf;
112e18a033bSKonstantin Ananyev
113e18a033bSKonstantin Ananyev    cf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module);
114e18a033bSKonstantin Ananyev
115e18a033bSKonstantin Ananyev    if (iocp == NULL) {
116e18a033bSKonstantin Ananyev        iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0,
117e18a033bSKonstantin Ananyev                                      cf->threads);
118e18a033bSKonstantin Ananyev    }
119e18a033bSKonstantin Ananyev
120e18a033bSKonstantin Ananyev    if (iocp == NULL) {
121e18a033bSKonstantin Ananyev        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
122e18a033bSKonstantin Ananyev                      "CreateIoCompletionPort() failed");
123e18a033bSKonstantin Ananyev        return NGX_ERROR;
124e18a033bSKonstantin Ananyev    }
125e18a033bSKonstantin Ananyev
126e18a033bSKonstantin Ananyev    ngx_io = ngx_iocp_io;
127e18a033bSKonstantin Ananyev
128e18a033bSKonstantin Ananyev    ngx_event_actions = ngx_iocp_module_ctx.actions;
129e18a033bSKonstantin Ananyev
130e18a033bSKonstantin Ananyev    ngx_event_flags = NGX_USE_IOCP_EVENT;
131e18a033bSKonstantin Ananyev
132e18a033bSKonstantin Ananyev    if (timer == 0) {
133e18a033bSKonstantin Ananyev        return NGX_OK;
134e18a033bSKonstantin Ananyev    }
135e18a033bSKonstantin Ananyev
136e18a033bSKonstantin Ananyev    /*
137e18a033bSKonstantin Ananyev     * The waitable timer could not be used, because
138e18a033bSKonstantin Ananyev     * GetQueuedCompletionStatus() does not set a thread to alertable state
139e18a033bSKonstantin Ananyev     */
140e18a033bSKonstantin Ananyev
141e18a033bSKonstantin Ananyev    if (timer_thread == NULL) {
142e18a033bSKonstantin Ananyev
143e18a033bSKonstantin Ananyev        msec = timer;
144e18a033bSKonstantin Ananyev
145e18a033bSKonstantin Ananyev        if (ngx_create_thread(&timer_thread, ngx_iocp_timer, &msec, cycle->log)
146e18a033bSKonstantin Ananyev            != 0)
147e18a033bSKonstantin Ananyev        {
148e18a033bSKonstantin Ananyev            return NGX_ERROR;
149e18a033bSKonstantin Ananyev        }
150e18a033bSKonstantin Ananyev    }
151e18a033bSKonstantin Ananyev
152e18a033bSKonstantin Ananyev    ngx_event_flags |= NGX_USE_TIMER_EVENT;
153e18a033bSKonstantin Ananyev
154e18a033bSKonstantin Ananyev    return NGX_OK;
155e18a033bSKonstantin Ananyev}
156e18a033bSKonstantin Ananyev
157e18a033bSKonstantin Ananyev
158e18a033bSKonstantin Ananyevstatic ngx_thread_value_t __stdcall
159e18a033bSKonstantin Ananyevngx_iocp_timer(void *data)
160e18a033bSKonstantin Ananyev{
161e18a033bSKonstantin Ananyev    ngx_msec_t  timer = *(ngx_msec_t *) data;
162e18a033bSKonstantin Ananyev
163e18a033bSKonstantin Ananyev    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
164e18a033bSKonstantin Ananyev                   "THREAD %p %p", &msec, data);
165e18a033bSKonstantin Ananyev
166e18a033bSKonstantin Ananyev    for ( ;; ) {
167e18a033bSKonstantin Ananyev        Sleep(timer);
168e18a033bSKonstantin Ananyev
169e18a033bSKonstantin Ananyev        ngx_time_update();
170e18a033bSKonstantin Ananyev#if 1
171e18a033bSKonstantin Ananyev        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer");
172e18a033bSKonstantin Ananyev#endif
173e18a033bSKonstantin Ananyev    }
174e18a033bSKonstantin Ananyev
175e18a033bSKonstantin Ananyev#if defined(__WATCOMC__) || defined(__GNUC__)
176e18a033bSKonstantin Ananyev    return 0;
177e18a033bSKonstantin Ananyev#endif
178e18a033bSKonstantin Ananyev}
179e18a033bSKonstantin Ananyev
180e18a033bSKonstantin Ananyev
181e18a033bSKonstantin Ananyevstatic void
182e18a033bSKonstantin Ananyevngx_iocp_done(ngx_cycle_t *cycle)
183e18a033bSKonstantin Ananyev{
184e18a033bSKonstantin Ananyev    if (CloseHandle(iocp) == -1) {
185e18a033bSKonstantin Ananyev        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
186e18a033bSKonstantin Ananyev                      "iocp CloseHandle() failed");
187e18a033bSKonstantin Ananyev    }
188e18a033bSKonstantin Ananyev
189e18a033bSKonstantin Ananyev    iocp = NULL;
190e18a033bSKonstantin Ananyev}
191e18a033bSKonstantin Ananyev
192e18a033bSKonstantin Ananyev
193e18a033bSKonstantin Ananyevstatic ngx_int_t
194e18a033bSKonstantin Ananyevngx_iocp_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t key)
195e18a033bSKonstantin Ananyev{
196e18a033bSKonstantin Ananyev    ngx_connection_t  *c;
197e18a033bSKonstantin Ananyev
198e18a033bSKonstantin Ananyev    c = (ngx_connection_t *) ev->data;
199e18a033bSKonstantin Ananyev
200e18a033bSKonstantin Ananyev    c->read->active = 1;
201e18a033bSKonstantin Ananyev    c->write->active = 1;
202e18a033bSKonstantin Ananyev
203e18a033bSKonstantin Ananyev    ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
204e18a033bSKonstantin Ananyev                   "iocp add: fd:%d k:%ui ov:%p", c->fd, key, &ev->ovlp);
205e18a033bSKonstantin Ananyev
206e18a033bSKonstantin Ananyev    if (CreateIoCompletionPort((HANDLE) c->fd, iocp, key, 0) == NULL) {
207e18a033bSKonstantin Ananyev        ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
208e18a033bSKonstantin Ananyev                      "CreateIoCompletionPort() failed");
209e18a033bSKonstantin Ananyev        return NGX_ERROR;
210e18a033bSKonstantin Ananyev    }
211e18a033bSKonstantin Ananyev
212e18a033bSKonstantin Ananyev    return NGX_OK;
213e18a033bSKonstantin Ananyev}
214e18a033bSKonstantin Ananyev
215e18a033bSKonstantin Ananyev
216e18a033bSKonstantin Ananyevstatic ngx_int_t
217e18a033bSKonstantin Ananyevngx_iocp_del_connection(ngx_connection_t *c, ngx_uint_t flags)
218e18a033bSKonstantin Ananyev{
219e18a033bSKonstantin Ananyev#if 0
220e18a033bSKonstantin Ananyev    if (flags & NGX_CLOSE_EVENT) {
221e18a033bSKonstantin Ananyev        return NGX_OK;
222e18a033bSKonstantin Ananyev    }
223e18a033bSKonstantin Ananyev
224e18a033bSKonstantin Ananyev    if (CancelIo((HANDLE) c->fd) == 0) {
225e18a033bSKonstantin Ananyev        ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, "CancelIo() failed");
226e18a033bSKonstantin Ananyev        return NGX_ERROR;
227e18a033bSKonstantin Ananyev    }
228e18a033bSKonstantin Ananyev#endif
229e18a033bSKonstantin Ananyev
230e18a033bSKonstantin Ananyev    return NGX_OK;
231e18a033bSKonstantin Ananyev}
232e18a033bSKonstantin Ananyev
233e18a033bSKonstantin Ananyev
234e18a033bSKonstantin Ananyevstatic
235e18a033bSKonstantin Ananyevngx_int_t ngx_iocp_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
236e18a033bSKonstantin Ananyev    ngx_uint_t flags)
237e18a033bSKonstantin Ananyev{
238e18a033bSKonstantin Ananyev    int                rc;
239e18a033bSKonstantin Ananyev    u_int              key;
240e18a033bSKonstantin Ananyev    u_long             bytes;
241e18a033bSKonstantin Ananyev    ngx_err_t          err;
242e18a033bSKonstantin Ananyev    ngx_msec_t         delta;
243e18a033bSKonstantin Ananyev    ngx_event_t       *ev;
244e18a033bSKonstantin Ananyev    ngx_event_ovlp_t  *ovlp;
245e18a033bSKonstantin Ananyev
246e18a033bSKonstantin Ananyev    if (timer == NGX_TIMER_INFINITE) {
247e18a033bSKonstantin Ananyev        timer = INFINITE;
248e18a033bSKonstantin Ananyev    }
249e18a033bSKonstantin Ananyev
250e18a033bSKonstantin Ananyev    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "iocp timer: %M", timer);
251e18a033bSKonstantin Ananyev
252e18a033bSKonstantin Ananyev    rc = GetQueuedCompletionStatus(iocp, &bytes, (PULONG_PTR) &key,
253e18a033bSKonstantin Ananyev                                   (LPOVERLAPPED *) &ovlp, (u_long) timer);
254e18a033bSKonstantin Ananyev
255e18a033bSKonstantin Ananyev    if (rc == 0) {
256e18a033bSKonstantin Ananyev        err = ngx_errno;
257e18a033bSKonstantin Ananyev    } else {
258e18a033bSKonstantin Ananyev        err = 0;
259e18a033bSKonstantin Ananyev    }
260e18a033bSKonstantin Ananyev
261e18a033bSKonstantin Ananyev    delta = ngx_current_msec;
262e18a033bSKonstantin Ananyev
263e18a033bSKonstantin Ananyev    if (flags & NGX_UPDATE_TIME) {
264e18a033bSKonstantin Ananyev        ngx_time_update();
265e18a033bSKonstantin Ananyev    }
266e18a033bSKonstantin Ananyev
267e18a033bSKonstantin Ananyev    ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
268e18a033bSKonstantin Ananyev                   "iocp: %d b:%d k:%d ov:%p", rc, bytes, key, ovlp);
269e18a033bSKonstantin Ananyev
270e18a033bSKonstantin Ananyev    if (timer != INFINITE) {
271e18a033bSKonstantin Ananyev        delta = ngx_current_msec - delta;
272e18a033bSKonstantin Ananyev
273e18a033bSKonstantin Ananyev        ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
274e18a033bSKonstantin Ananyev                       "iocp timer: %M, delta: %M", timer, delta);
275e18a033bSKonstantin Ananyev    }
276e18a033bSKonstantin Ananyev
277e18a033bSKonstantin Ananyev    if (err) {
278e18a033bSKonstantin Ananyev        if (ovlp == NULL) {
279e18a033bSKonstantin Ananyev            if (err != WAIT_TIMEOUT) {
280e18a033bSKonstantin Ananyev                ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
281e18a033bSKonstantin Ananyev                              "GetQueuedCompletionStatus() failed");
282e18a033bSKonstantin Ananyev
283e18a033bSKonstantin Ananyev                return NGX_ERROR;
284e18a033bSKonstantin Ananyev            }
285e18a033bSKonstantin Ananyev
286e18a033bSKonstantin Ananyev            return NGX_OK;
287e18a033bSKonstantin Ananyev        }
288e18a033bSKonstantin Ananyev
289e18a033bSKonstantin Ananyev        ovlp->error = err;
290e18a033bSKonstantin Ananyev    }
291e18a033bSKonstantin Ananyev
292e18a033bSKonstantin Ananyev    if (ovlp == NULL) {
293e18a033bSKonstantin Ananyev        ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
294e18a033bSKonstantin Ananyev                      "GetQueuedCompletionStatus() returned no operation");
295e18a033bSKonstantin Ananyev        return NGX_ERROR;
296e18a033bSKonstantin Ananyev    }
297e18a033bSKonstantin Ananyev
298e18a033bSKonstantin Ananyev
299e18a033bSKonstantin Ananyev    ev = ovlp->event;
300e18a033bSKonstantin Ananyev
301e18a033bSKonstantin Ananyev    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, err, "iocp event:%p", ev);
302e18a033bSKonstantin Ananyev
303e18a033bSKonstantin Ananyev
304e18a033bSKonstantin Ananyev    if (err == ERROR_NETNAME_DELETED /* the socket was closed */
305e18a033bSKonstantin Ananyev        || err == ERROR_OPERATION_ABORTED /* the operation was canceled */)
306e18a033bSKonstantin Ananyev    {
307e18a033bSKonstantin Ananyev
308e18a033bSKonstantin Ananyev        /*
309e18a033bSKonstantin Ananyev         * the WSA_OPERATION_ABORTED completion notification
310e18a033bSKonstantin Ananyev         * for a file descriptor that was closed
311e18a033bSKonstantin Ananyev         */
312e18a033bSKonstantin Ananyev
313e18a033bSKonstantin Ananyev        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, err,
314e18a033bSKonstantin Ananyev                       "iocp: aborted event %p", ev);
315e18a033bSKonstantin Ananyev
316e18a033bSKonstantin Ananyev        return NGX_OK;
317e18a033bSKonstantin Ananyev    }
318e18a033bSKonstantin Ananyev
319e18a033bSKonstantin Ananyev    if (err) {
320e18a033bSKonstantin Ananyev        ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
321e18a033bSKonstantin Ananyev                      "GetQueuedCompletionStatus() returned operation error");
322e18a033bSKonstantin Ananyev    }
323e18a033bSKonstantin Ananyev
324e18a033bSKonstantin Ananyev    switch (key) {
325e18a033bSKonstantin Ananyev
326e18a033bSKonstantin Ananyev    case NGX_IOCP_ACCEPT:
327e18a033bSKonstantin Ananyev        if (bytes) {
328e18a033bSKonstantin Ananyev            ev->ready = 1;
329e18a033bSKonstantin Ananyev        }
330e18a033bSKonstantin Ananyev        break;
331e18a033bSKonstantin Ananyev
332e18a033bSKonstantin Ananyev    case NGX_IOCP_IO:
333e18a033bSKonstantin Ananyev        ev->complete = 1;
334e18a033bSKonstantin Ananyev        ev->ready = 1;
335e18a033bSKonstantin Ananyev        break;
336e18a033bSKonstantin Ananyev
337e18a033bSKonstantin Ananyev    case NGX_IOCP_CONNECT:
338e18a033bSKonstantin Ananyev        ev->ready = 1;
339e18a033bSKonstantin Ananyev    }
340e18a033bSKonstantin Ananyev
341e18a033bSKonstantin Ananyev    ev->available = bytes;
342e18a033bSKonstantin Ananyev
343e18a033bSKonstantin Ananyev    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
344e18a033bSKonstantin Ananyev                   "iocp event handler: %p", ev->handler);
345e18a033bSKonstantin Ananyev
346e18a033bSKonstantin Ananyev    ev->handler(ev);
347e18a033bSKonstantin Ananyev
348e18a033bSKonstantin Ananyev    return NGX_OK;
349e18a033bSKonstantin Ananyev}
350e18a033bSKonstantin Ananyev
351e18a033bSKonstantin Ananyev
352e18a033bSKonstantin Ananyevstatic void *
353e18a033bSKonstantin Ananyevngx_iocp_create_conf(ngx_cycle_t *cycle)
354e18a033bSKonstantin Ananyev{
355e18a033bSKonstantin Ananyev    ngx_iocp_conf_t  *cf;
356e18a033bSKonstantin Ananyev
357e18a033bSKonstantin Ananyev    cf = ngx_palloc(cycle->pool, sizeof(ngx_iocp_conf_t));
358e18a033bSKonstantin Ananyev    if (cf == NULL) {
359e18a033bSKonstantin Ananyev        return NGX_CONF_ERROR;
360e18a033bSKonstantin Ananyev    }
361e18a033bSKonstantin Ananyev
362e18a033bSKonstantin Ananyev    cf->threads = NGX_CONF_UNSET;
363e18a033bSKonstantin Ananyev    cf->post_acceptex = NGX_CONF_UNSET;
364e18a033bSKonstantin Ananyev    cf->acceptex_read = NGX_CONF_UNSET;
365e18a033bSKonstantin Ananyev
366e18a033bSKonstantin Ananyev    return cf;
367e18a033bSKonstantin Ananyev}
368e18a033bSKonstantin Ananyev
369e18a033bSKonstantin Ananyev
370e18a033bSKonstantin Ananyevstatic char *
371e18a033bSKonstantin Ananyevngx_iocp_init_conf(ngx_cycle_t *cycle, void *conf)
372e18a033bSKonstantin Ananyev{
373e18a033bSKonstantin Ananyev    ngx_iocp_conf_t *cf = conf;
374e18a033bSKonstantin Ananyev
375e18a033bSKonstantin Ananyev    ngx_conf_init_value(cf->threads, 0);
376e18a033bSKonstantin Ananyev    ngx_conf_init_value(cf->post_acceptex, 10);
377e18a033bSKonstantin Ananyev    ngx_conf_init_value(cf->acceptex_read, 1);
378e18a033bSKonstantin Ananyev
379e18a033bSKonstantin Ananyev    return NGX_CONF_OK;
380e18a033bSKonstantin Ananyev}
381