Annotation of embedaddon/nginx/src/event/modules/ngx_eventport_module.c, revision 1.1

1.1     ! misho       1: 
        !             2: /*
        !             3:  * Copyright (C) Igor Sysoev
        !             4:  * Copyright (C) Nginx, Inc.
        !             5:  */
        !             6: 
        !             7: 
        !             8: #include <ngx_config.h>
        !             9: #include <ngx_core.h>
        !            10: #include <ngx_event.h>
        !            11: 
        !            12: 
        !            13: #if (NGX_TEST_BUILD_EVENTPORT)
        !            14: 
        !            15: #define ushort_t  u_short
        !            16: #define uint_t    u_int
        !            17: 
        !            18: #ifndef CLOCK_REALTIME
        !            19: #define CLOCK_REALTIME          0
        !            20: typedef int     clockid_t;
        !            21: typedef void *  timer_t;
        !            22: #endif
        !            23: 
        !            24: /* Solaris declarations */
        !            25: 
        !            26: #define PORT_SOURCE_AIO         1
        !            27: #define PORT_SOURCE_TIMER       2
        !            28: #define PORT_SOURCE_USER        3
        !            29: #define PORT_SOURCE_FD          4
        !            30: #define PORT_SOURCE_ALERT       5
        !            31: #define PORT_SOURCE_MQ          6
        !            32: 
        !            33: #ifndef ETIME
        !            34: #define ETIME                   64
        !            35: #endif
        !            36: 
        !            37: #define SIGEV_PORT              4
        !            38: 
        !            39: typedef struct {
        !            40:     int         portev_events;  /* event data is source specific */
        !            41:     ushort_t    portev_source;  /* event source */
        !            42:     ushort_t    portev_pad;     /* port internal use */
        !            43:     uintptr_t   portev_object;  /* source specific object */
        !            44:     void       *portev_user;    /* user cookie */
        !            45: } port_event_t;
        !            46: 
        !            47: typedef struct  port_notify {
        !            48:     int         portnfy_port;   /* bind request(s) to port */
        !            49:     void       *portnfy_user;   /* user defined */
        !            50: } port_notify_t;
        !            51: 
        !            52: #if (__FreeBSD_version < 700005)
        !            53: 
        !            54: typedef struct itimerspec {     /* definition per POSIX.4 */
        !            55:     struct timespec it_interval;/* timer period */
        !            56:     struct timespec it_value;   /* timer expiration */
        !            57: } itimerspec_t;
        !            58: 
        !            59: #endif
        !            60: 
        !            61: int port_create(void);
        !            62: 
        !            63: int port_create(void)
        !            64: {
        !            65:     return -1;
        !            66: }
        !            67: 
        !            68: 
        !            69: int port_associate(int port, int source, uintptr_t object, int events,
        !            70:     void *user);
        !            71: 
        !            72: int port_associate(int port, int source, uintptr_t object, int events,
        !            73:     void *user)
        !            74: {
        !            75:     return -1;
        !            76: }
        !            77: 
        !            78: 
        !            79: int port_dissociate(int port, int source, uintptr_t object);
        !            80: 
        !            81: int port_dissociate(int port, int source, uintptr_t object)
        !            82: {
        !            83:     return -1;
        !            84: }
        !            85: 
        !            86: 
        !            87: int port_getn(int port, port_event_t list[], uint_t max, uint_t *nget,
        !            88:     struct timespec *timeout);
        !            89: 
        !            90: int port_getn(int port, port_event_t list[], uint_t max, uint_t *nget,
        !            91:     struct timespec *timeout)
        !            92: {
        !            93:     return -1;
        !            94: }
        !            95: 
        !            96: 
        !            97: int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid);
        !            98: 
        !            99: int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
        !           100: {
        !           101:     return -1;
        !           102: }
        !           103: 
        !           104: 
        !           105: int timer_settime(timer_t timerid, int flags, const struct itimerspec *value,
        !           106:     struct itimerspec *ovalue);
        !           107: 
        !           108: int timer_settime(timer_t timerid, int flags, const struct itimerspec *value,
        !           109:     struct itimerspec *ovalue)
        !           110: {
        !           111:     return -1;
        !           112: }
        !           113: 
        !           114: 
        !           115: int timer_delete(timer_t timerid);
        !           116: 
        !           117: int timer_delete(timer_t timerid)
        !           118: {
        !           119:     return -1;
        !           120: }
        !           121: 
        !           122: #endif
        !           123: 
        !           124: 
        !           125: typedef struct {
        !           126:     ngx_uint_t  events;
        !           127: } ngx_eventport_conf_t;
        !           128: 
        !           129: 
        !           130: static ngx_int_t ngx_eventport_init(ngx_cycle_t *cycle, ngx_msec_t timer);
        !           131: static void ngx_eventport_done(ngx_cycle_t *cycle);
        !           132: static ngx_int_t ngx_eventport_add_event(ngx_event_t *ev, ngx_int_t event,
        !           133:     ngx_uint_t flags);
        !           134: static ngx_int_t ngx_eventport_del_event(ngx_event_t *ev, ngx_int_t event,
        !           135:     ngx_uint_t flags);
        !           136: static ngx_int_t ngx_eventport_process_events(ngx_cycle_t *cycle,
        !           137:     ngx_msec_t timer, ngx_uint_t flags);
        !           138: 
        !           139: static void *ngx_eventport_create_conf(ngx_cycle_t *cycle);
        !           140: static char *ngx_eventport_init_conf(ngx_cycle_t *cycle, void *conf);
        !           141: 
        !           142: static int            ep = -1;
        !           143: static port_event_t  *event_list;
        !           144: static ngx_uint_t     nevents;
        !           145: static timer_t        event_timer = (timer_t) -1;
        !           146: 
        !           147: static ngx_str_t      eventport_name = ngx_string("eventport");
        !           148: 
        !           149: 
        !           150: static ngx_command_t  ngx_eventport_commands[] = {
        !           151: 
        !           152:     { ngx_string("eventport_events"),
        !           153:       NGX_EVENT_CONF|NGX_CONF_TAKE1,
        !           154:       ngx_conf_set_num_slot,
        !           155:       0,
        !           156:       offsetof(ngx_eventport_conf_t, events),
        !           157:       NULL },
        !           158: 
        !           159:       ngx_null_command
        !           160: };
        !           161: 
        !           162: 
        !           163: ngx_event_module_t  ngx_eventport_module_ctx = {
        !           164:     &eventport_name,
        !           165:     ngx_eventport_create_conf,             /* create configuration */
        !           166:     ngx_eventport_init_conf,               /* init configuration */
        !           167: 
        !           168:     {
        !           169:         ngx_eventport_add_event,           /* add an event */
        !           170:         ngx_eventport_del_event,           /* delete an event */
        !           171:         ngx_eventport_add_event,           /* enable an event */
        !           172:         ngx_eventport_del_event,           /* disable an event */
        !           173:         NULL,                              /* add an connection */
        !           174:         NULL,                              /* delete an connection */
        !           175:         NULL,                              /* process the changes */
        !           176:         ngx_eventport_process_events,      /* process the events */
        !           177:         ngx_eventport_init,                /* init the events */
        !           178:         ngx_eventport_done,                /* done the events */
        !           179:     }
        !           180: 
        !           181: };
        !           182: 
        !           183: ngx_module_t  ngx_eventport_module = {
        !           184:     NGX_MODULE_V1,
        !           185:     &ngx_eventport_module_ctx,             /* module context */
        !           186:     ngx_eventport_commands,                /* module directives */
        !           187:     NGX_EVENT_MODULE,                      /* module type */
        !           188:     NULL,                                  /* init master */
        !           189:     NULL,                                  /* init module */
        !           190:     NULL,                                  /* init process */
        !           191:     NULL,                                  /* init thread */
        !           192:     NULL,                                  /* exit thread */
        !           193:     NULL,                                  /* exit process */
        !           194:     NULL,                                  /* exit master */
        !           195:     NGX_MODULE_V1_PADDING
        !           196: };
        !           197: 
        !           198: 
        !           199: static ngx_int_t
        !           200: ngx_eventport_init(ngx_cycle_t *cycle, ngx_msec_t timer)
        !           201: {
        !           202:     port_notify_t          pn;
        !           203:     struct itimerspec      its;
        !           204:     struct sigevent        sev;
        !           205:     ngx_eventport_conf_t  *epcf;
        !           206: 
        !           207:     epcf = ngx_event_get_conf(cycle->conf_ctx, ngx_eventport_module);
        !           208: 
        !           209:     if (ep == -1) {
        !           210:         ep = port_create();
        !           211: 
        !           212:         if (ep == -1) {
        !           213:             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
        !           214:                           "port_create() failed");
        !           215:             return NGX_ERROR;
        !           216:         }
        !           217:     }
        !           218: 
        !           219:     if (nevents < epcf->events) {
        !           220:         if (event_list) {
        !           221:             ngx_free(event_list);
        !           222:         }
        !           223: 
        !           224:         event_list = ngx_alloc(sizeof(port_event_t) * epcf->events,
        !           225:                                cycle->log);
        !           226:         if (event_list == NULL) {
        !           227:             return NGX_ERROR;
        !           228:         }
        !           229:     }
        !           230: 
        !           231:     ngx_event_flags = NGX_USE_EVENTPORT_EVENT;
        !           232: 
        !           233:     if (timer) {
        !           234:         ngx_memzero(&pn, sizeof(port_notify_t));
        !           235:         pn.portnfy_port = ep;
        !           236: 
        !           237:         ngx_memzero(&sev, sizeof(struct sigevent));
        !           238:         sev.sigev_notify = SIGEV_PORT;
        !           239: #if !(NGX_TEST_BUILD_EVENTPORT)
        !           240:         sev.sigev_value.sival_ptr = &pn;
        !           241: #endif
        !           242: 
        !           243:         if (timer_create(CLOCK_REALTIME, &sev, &event_timer) == -1) {
        !           244:             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
        !           245:                           "timer_create() failed");
        !           246:             return NGX_ERROR;
        !           247:         }
        !           248: 
        !           249:         its.it_interval.tv_sec = timer / 1000;
        !           250:         its.it_interval.tv_nsec = (timer % 1000) * 1000000;
        !           251:         its.it_value.tv_sec = timer / 1000;
        !           252:         its.it_value.tv_nsec = (timer % 1000) * 1000000;
        !           253: 
        !           254:         if (timer_settime(event_timer, 0, &its, NULL) == -1) {
        !           255:             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
        !           256:                           "timer_settime() failed");
        !           257:             return NGX_ERROR;
        !           258:         }
        !           259: 
        !           260:         ngx_event_flags |= NGX_USE_TIMER_EVENT;
        !           261:     }
        !           262: 
        !           263:     nevents = epcf->events;
        !           264: 
        !           265:     ngx_io = ngx_os_io;
        !           266: 
        !           267:     ngx_event_actions = ngx_eventport_module_ctx.actions;
        !           268: 
        !           269:     return NGX_OK;
        !           270: }
        !           271: 
        !           272: 
        !           273: static void
        !           274: ngx_eventport_done(ngx_cycle_t *cycle)
        !           275: {
        !           276:     if (event_timer != (timer_t) -1) {
        !           277:         if (timer_delete(event_timer) == -1) {
        !           278:             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
        !           279:                           "timer_delete() failed");
        !           280:         }
        !           281: 
        !           282:         event_timer = (timer_t) -1;
        !           283:     }
        !           284: 
        !           285:     if (close(ep) == -1) {
        !           286:         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
        !           287:                       "close() event port failed");
        !           288:     }
        !           289: 
        !           290:     ep = -1;
        !           291: 
        !           292:     ngx_free(event_list);
        !           293: 
        !           294:     event_list = NULL;
        !           295:     nevents = 0;
        !           296: }
        !           297: 
        !           298: 
        !           299: static ngx_int_t
        !           300: ngx_eventport_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
        !           301: {
        !           302:     ngx_int_t          events, prev;
        !           303:     ngx_event_t       *e;
        !           304:     ngx_connection_t  *c;
        !           305: 
        !           306:     c = ev->data;
        !           307: 
        !           308:     events = event;
        !           309: 
        !           310:     if (event == NGX_READ_EVENT) {
        !           311:         e = c->write;
        !           312:         prev = POLLOUT;
        !           313: #if (NGX_READ_EVENT != POLLIN)
        !           314:         events = POLLIN;
        !           315: #endif
        !           316: 
        !           317:     } else {
        !           318:         e = c->read;
        !           319:         prev = POLLIN;
        !           320: #if (NGX_WRITE_EVENT != POLLOUT)
        !           321:         events = POLLOUT;
        !           322: #endif
        !           323:     }
        !           324: 
        !           325:     if (e->oneshot) {
        !           326:         events |= prev;
        !           327:     }
        !           328: 
        !           329:     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
        !           330:                    "eventport add event: fd:%d ev:%04Xi", c->fd, events);
        !           331: 
        !           332:     if (port_associate(ep, PORT_SOURCE_FD, c->fd, events,
        !           333:                        (void *) ((uintptr_t) ev | ev->instance))
        !           334:         == -1)
        !           335:     {
        !           336:         ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
        !           337:                       "port_associate() failed");
        !           338:         return NGX_ERROR;
        !           339:     }
        !           340: 
        !           341:     ev->active = 1;
        !           342:     ev->oneshot = 1;
        !           343: 
        !           344:     return NGX_OK;
        !           345: }
        !           346: 
        !           347: 
        !           348: static ngx_int_t
        !           349: ngx_eventport_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
        !           350: {
        !           351:     ngx_event_t       *e;
        !           352:     ngx_connection_t  *c;
        !           353: 
        !           354:     /*
        !           355:      * when the file descriptor is closed, the event port automatically
        !           356:      * dissociates it from the port, so we do not need to dissociate explicitly
        !           357:      * the event before the closing the file descriptor
        !           358:      */
        !           359: 
        !           360:     if (flags & NGX_CLOSE_EVENT) {
        !           361:         ev->active = 0;
        !           362:         ev->oneshot = 0;
        !           363:         return NGX_OK;
        !           364:     }
        !           365: 
        !           366:     c = ev->data;
        !           367: 
        !           368:     if (event == NGX_READ_EVENT) {
        !           369:         e = c->write;
        !           370:         event = POLLOUT;
        !           371: 
        !           372:     } else {
        !           373:         e = c->read;
        !           374:         event = POLLIN;
        !           375:     }
        !           376: 
        !           377:     if (e->oneshot) {
        !           378:         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
        !           379:                        "eventport change event: fd:%d ev:%04Xi", c->fd, event);
        !           380: 
        !           381:         if (port_associate(ep, PORT_SOURCE_FD, c->fd, event,
        !           382:                            (void *) ((uintptr_t) ev | ev->instance))
        !           383:             == -1)
        !           384:         {
        !           385:             ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
        !           386:                           "port_associate() failed");
        !           387:             return NGX_ERROR;
        !           388:         }
        !           389: 
        !           390:     } else {
        !           391:         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
        !           392:                        "eventport del event: fd:%d", c->fd);
        !           393: 
        !           394:         if (port_dissociate(ep, PORT_SOURCE_FD, c->fd) == -1) {
        !           395:             ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
        !           396:                           "port_dissociate() failed");
        !           397:             return NGX_ERROR;
        !           398:         }
        !           399:     }
        !           400: 
        !           401:     ev->active = 0;
        !           402:     ev->oneshot = 0;
        !           403: 
        !           404:     return NGX_OK;
        !           405: }
        !           406: 
        !           407: 
        !           408: ngx_int_t
        !           409: ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
        !           410:     ngx_uint_t flags)
        !           411: {
        !           412:     int                 n, revents;
        !           413:     u_int               events;
        !           414:     ngx_err_t           err;
        !           415:     ngx_int_t           instance;
        !           416:     ngx_uint_t          i, level;
        !           417:     ngx_event_t        *ev, *rev, *wev, **queue;
        !           418:     ngx_connection_t   *c;
        !           419:     struct timespec     ts, *tp;
        !           420: 
        !           421:     if (timer == NGX_TIMER_INFINITE) {
        !           422:         tp = NULL;
        !           423: 
        !           424:     } else {
        !           425:         ts.tv_sec = timer / 1000;
        !           426:         ts.tv_nsec = (timer % 1000) * 1000000;
        !           427:         tp = &ts;
        !           428:     }
        !           429: 
        !           430:     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
        !           431:                    "eventport timer: %M", timer);
        !           432: 
        !           433:     events = 1;
        !           434: 
        !           435:     n = port_getn(ep, event_list, (u_int) nevents, &events, tp);
        !           436: 
        !           437:     err = ngx_errno;
        !           438: 
        !           439:     if (flags & NGX_UPDATE_TIME) {
        !           440:         ngx_time_update();
        !           441:     }
        !           442: 
        !           443:     if (n == -1) {
        !           444:         if (err == ETIME) {
        !           445:             if (timer != NGX_TIMER_INFINITE) {
        !           446:                 return NGX_OK;
        !           447:             }
        !           448: 
        !           449:             ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
        !           450:                           "port_getn() returned no events without timeout");
        !           451:             return NGX_ERROR;
        !           452:         }
        !           453: 
        !           454:         level = (err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT;
        !           455:         ngx_log_error(level, cycle->log, err, "port_getn() failed");
        !           456:         return NGX_ERROR;
        !           457:     }
        !           458: 
        !           459:     if (events == 0) {
        !           460:         if (timer != NGX_TIMER_INFINITE) {
        !           461:             return NGX_OK;
        !           462:         }
        !           463: 
        !           464:         ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
        !           465:                       "port_getn() returned no events without timeout");
        !           466:         return NGX_ERROR;
        !           467:     }
        !           468: 
        !           469:     ngx_mutex_lock(ngx_posted_events_mutex);
        !           470: 
        !           471:     for (i = 0; i < events; i++) {
        !           472: 
        !           473:         if (event_list[i].portev_source == PORT_SOURCE_TIMER) {
        !           474:             ngx_time_update();
        !           475:             continue;
        !           476:         }
        !           477: 
        !           478:         ev = event_list[i].portev_user;
        !           479: 
        !           480:         switch (event_list[i].portev_source) {
        !           481: 
        !           482:         case PORT_SOURCE_FD:
        !           483: 
        !           484:             instance = (uintptr_t) ev & 1;
        !           485:             ev = (ngx_event_t *) ((uintptr_t) ev & (uintptr_t) ~1);
        !           486: 
        !           487:             if (ev->closed || ev->instance != instance) {
        !           488: 
        !           489:                 /*
        !           490:                  * the stale event from a file descriptor
        !           491:                  * that was just closed in this iteration
        !           492:                  */
        !           493: 
        !           494:                 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
        !           495:                                "eventport: stale event %p", ev);
        !           496:                 continue;
        !           497:             }
        !           498: 
        !           499:             revents = event_list[i].portev_events;
        !           500: 
        !           501:             ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
        !           502:                            "eventport: fd:%d, ev:%04Xd",
        !           503:                            event_list[i].portev_object, revents);
        !           504: 
        !           505:             if (revents & (POLLERR|POLLHUP|POLLNVAL)) {
        !           506:                 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
        !           507:                                "port_getn() error fd:%d ev:%04Xd",
        !           508:                                event_list[i].portev_object, revents);
        !           509:             }
        !           510: 
        !           511:             if (revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) {
        !           512:                 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
        !           513:                               "strange port_getn() events fd:%d ev:%04Xd",
        !           514:                               event_list[i].portev_object, revents);
        !           515:             }
        !           516: 
        !           517:             if ((revents & (POLLERR|POLLHUP|POLLNVAL))
        !           518:                  && (revents & (POLLIN|POLLOUT)) == 0)
        !           519:             {
        !           520:                 /*
        !           521:                  * if the error events were returned without POLLIN or POLLOUT,
        !           522:                  * then add these flags to handle the events at least in one
        !           523:                  * active handler
        !           524:                  */
        !           525: 
        !           526:                 revents |= POLLIN|POLLOUT;
        !           527:             }
        !           528: 
        !           529:             c = ev->data;
        !           530:             rev = c->read;
        !           531:             wev = c->write;
        !           532: 
        !           533:             rev->active = 0;
        !           534:             wev->active = 0;
        !           535: 
        !           536:             if (revents & POLLIN) {
        !           537: 
        !           538:                 if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
        !           539:                     rev->posted_ready = 1;
        !           540: 
        !           541:                 } else {
        !           542:                     rev->ready = 1;
        !           543:                 }
        !           544: 
        !           545:                 if (flags & NGX_POST_EVENTS) {
        !           546:                     queue = (ngx_event_t **) (rev->accept ?
        !           547:                                &ngx_posted_accept_events : &ngx_posted_events);
        !           548: 
        !           549:                     ngx_locked_post_event(rev, queue);
        !           550: 
        !           551:                 } else {
        !           552:                     rev->handler(rev);
        !           553: 
        !           554:                     if (ev->closed || ev->instance != instance) {
        !           555:                         continue;
        !           556:                     }
        !           557:                 }
        !           558: 
        !           559:                 if (rev->accept) {
        !           560:                     if (ngx_use_accept_mutex) {
        !           561:                         ngx_accept_events = 1;
        !           562:                         continue;
        !           563:                     }
        !           564: 
        !           565:                     if (port_associate(ep, PORT_SOURCE_FD, c->fd, POLLIN,
        !           566:                                        (void *) ((uintptr_t) ev | ev->instance))
        !           567:                         == -1)
        !           568:                     {
        !           569:                         ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
        !           570:                                       "port_associate() failed");
        !           571:                         return NGX_ERROR;
        !           572:                     }
        !           573:                 }
        !           574:             }
        !           575: 
        !           576:             if (revents & POLLOUT) {
        !           577: 
        !           578:                 if (flags & NGX_POST_THREAD_EVENTS) {
        !           579:                     wev->posted_ready = 1;
        !           580: 
        !           581:                 } else {
        !           582:                     wev->ready = 1;
        !           583:                 }
        !           584: 
        !           585:                 if (flags & NGX_POST_EVENTS) {
        !           586:                     ngx_locked_post_event(wev, &ngx_posted_events);
        !           587: 
        !           588:                 } else {
        !           589:                     wev->handler(wev);
        !           590:                 }
        !           591:             }
        !           592: 
        !           593:             continue;
        !           594: 
        !           595:         default:
        !           596:             ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
        !           597:                           "unexpected even_port object %d",
        !           598:                           event_list[i].portev_object);
        !           599:             continue;
        !           600:         }
        !           601:     }
        !           602: 
        !           603:     ngx_mutex_unlock(ngx_posted_events_mutex);
        !           604: 
        !           605:     return NGX_OK;
        !           606: }
        !           607: 
        !           608: 
        !           609: static void *
        !           610: ngx_eventport_create_conf(ngx_cycle_t *cycle)
        !           611: {
        !           612:     ngx_eventport_conf_t  *epcf;
        !           613: 
        !           614:     epcf = ngx_palloc(cycle->pool, sizeof(ngx_eventport_conf_t));
        !           615:     if (epcf == NULL) {
        !           616:         return NULL;
        !           617:     }
        !           618: 
        !           619:     epcf->events = NGX_CONF_UNSET;
        !           620: 
        !           621:     return epcf;
        !           622: }
        !           623: 
        !           624: 
        !           625: static char *
        !           626: ngx_eventport_init_conf(ngx_cycle_t *cycle, void *conf)
        !           627: {
        !           628:     ngx_eventport_conf_t *epcf = conf;
        !           629: 
        !           630:     ngx_conf_init_uint_value(epcf->events, 32);
        !           631: 
        !           632:     return NGX_CONF_OK;
        !           633: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>