📄 ngx_eventport_module.c
字号:
/* * Copyright (C) Igor Sysoev */#include <ngx_config.h>#include <ngx_core.h>#include <ngx_event.h>#if (NGX_TEST_BUILD_EVENTPORT)#define ushort_t u_short#define uint_t u_int/* Solaris declarations */#define PORT_SOURCE_AIO 1#define PORT_SOURCE_TIMER 2#define PORT_SOURCE_USER 3#define PORT_SOURCE_FD 4#define PORT_SOURCE_ALERT 5#define PORT_SOURCE_MQ 6#define ETIME 64#define SIGEV_PORT 4typedef struct { int portev_events; /* event data is source specific */ ushort_t portev_source; /* event source */ ushort_t portev_pad; /* port internal use */ uintptr_t portev_object; /* source specific object */ void *portev_user; /* user cookie */} port_event_t;typedef struct port_notify { int portnfy_port; /* bind request(s) to port */ void *portnfy_user; /* user defined */} port_notify_t;typedef struct itimerspec { /* definition per POSIX.4 */ struct timespec it_interval;/* timer period */ struct timespec it_value; /* timer expiration */} itimerspec_t;int port_create(void){ return -1;}int port_associate(int port, int source, uintptr_t object, int events, void *user){ return -1;}int port_dissociate(int port, int source, uintptr_t object){ return -1;}int port_getn(int port, port_event_t list[], uint_t max, uint_t *nget, struct timespec *timeout){ return -1;}int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid){ return -1;}int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue){ return -1;}int timer_delete(timer_t timerid){ return -1;}#endiftypedef struct { ngx_uint_t events;} ngx_eventport_conf_t;static ngx_int_t ngx_eventport_init(ngx_cycle_t *cycle, ngx_msec_t timer);static void ngx_eventport_done(ngx_cycle_t *cycle);static ngx_int_t ngx_eventport_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);static ngx_int_t ngx_eventport_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);static ngx_int_t ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags);static void *ngx_eventport_create_conf(ngx_cycle_t *cycle);static char *ngx_eventport_init_conf(ngx_cycle_t *cycle, void *conf);static int ep = -1;static port_event_t *event_list;static ngx_uint_t nevents;static timer_t event_timer = -1;static ngx_str_t eventport_name = ngx_string("eventport");static ngx_command_t ngx_eventport_commands[] = { { ngx_string("eventport_events"), NGX_EVENT_CONF|NGX_CONF_TAKE1, ngx_conf_set_num_slot, 0, offsetof(ngx_eventport_conf_t, events), NULL }, ngx_null_command};ngx_event_module_t ngx_eventport_module_ctx = { &eventport_name, ngx_eventport_create_conf, /* create configuration */ ngx_eventport_init_conf, /* init configuration */ { ngx_eventport_add_event, /* add an event */ ngx_eventport_del_event, /* delete an event */ ngx_eventport_add_event, /* enable an event */ ngx_eventport_del_event, /* disable an event */ NULL, /* add an connection */ NULL, /* delete an connection */ NULL, /* process the changes */ ngx_eventport_process_events, /* process the events */ ngx_eventport_init, /* init the events */ ngx_eventport_done, /* done the events */ }};ngx_module_t ngx_eventport_module = { NGX_MODULE_V1, &ngx_eventport_module_ctx, /* module context */ ngx_eventport_commands, /* module directives */ NGX_EVENT_MODULE, /* module type */ NULL, /* init master */ NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ NULL, /* exit process */ NULL, /* exit master */ NGX_MODULE_V1_PADDING};static ngx_int_tngx_eventport_init(ngx_cycle_t *cycle, ngx_msec_t timer){ port_notify_t pn; struct itimerspec its; struct sigevent sev; ngx_eventport_conf_t *epcf; epcf = ngx_event_get_conf(cycle->conf_ctx, ngx_eventport_module); if (ep == -1) { ep = port_create(); if (ep == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "port_create() failed"); return NGX_ERROR; } } if (nevents < epcf->events) { if (event_list) { ngx_free(event_list); } event_list = ngx_alloc(sizeof(port_event_t) * epcf->events, cycle->log); if (event_list == NULL) { return NGX_ERROR; } } ngx_event_flags = NGX_USE_EVENTPORT_EVENT; if (timer) { ngx_memzero(&pn, sizeof(port_notify_t)); pn.portnfy_port = ep; ngx_memzero(&sev, sizeof(struct sigevent)); sev.sigev_notify = SIGEV_PORT;#if !(NGX_TEST_BUILD_EVENTPORT) sev.sigev_value.sival_ptr = &pn;#endif if (timer_create(CLOCK_REALTIME, &sev, &event_timer) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "timer_create() failed"); return NGX_ERROR; } its.it_interval.tv_sec = timer / 1000; its.it_interval.tv_nsec = (timer % 1000) * 1000000; its.it_value.tv_sec = timer / 1000; its.it_value.tv_nsec = (timer % 1000) * 1000000; if (timer_settime(event_timer, 0, &its, NULL) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "timer_settime() failed"); return NGX_ERROR; } ngx_event_flags |= NGX_USE_TIMER_EVENT; } nevents = epcf->events; ngx_io = ngx_os_io; ngx_event_actions = ngx_eventport_module_ctx.actions; return NGX_OK;}static voidngx_eventport_done(ngx_cycle_t *cycle){ if (event_timer != -1) { if (timer_delete(event_timer) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "timer_delete() failed"); } event_timer = -1; } if (close(ep) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "close() event port failed"); } ep = -1; ngx_free(event_list); event_list = NULL; nevents = 0;}static ngx_int_tngx_eventport_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags){ ngx_int_t events, prev; ngx_event_t *e; ngx_connection_t *c; c = ev->data; events = event; if (event == NGX_READ_EVENT) { e = c->write; prev = POLLOUT;#if (NGX_READ_EVENT != POLLIN) events = POLLIN;#endif } else { e = c->read; prev = POLLIN;#if (NGX_WRITE_EVENT != POLLOUT) events = POLLOUT;#endif } if (e->oneshot) { events |= prev; } ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, "eventport add event: fd:%d ev:%04Xi", c->fd, events); if (port_associate(ep, PORT_SOURCE_FD, c->fd, events, (void *) ((uintptr_t) ev | ev->instance)) == -1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -