Skip to content

Commit f083783

Browse files
committed
feature: support socket in some block phase
1 parent fdf752d commit f083783

8 files changed

+723
-5
lines changed

config

+13
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,18 @@ HTTP_LUA_SRCS=" \
298298
$ngx_addon_dir/src/ngx_http_lua_pipe.c \
299299
"
300300

301+
if echo "$EVENT_MODULES" | grep ngx_epoll_module 2>&1 >/dev/null; then
302+
HTTP_LUA_SRCS="$HTTP_LUA_SRCS $ngx_addon_dir/src/event/ngx_http_lua_epoll.c"
303+
fi
304+
305+
if echo "$EVENT_MODULES" | grep ngx_poll_module 2>&1 >/dev/null; then
306+
HTTP_LUA_SRCS="$HTTP_LUA_SRCS $ngx_addon_dir/src/event/ngx_http_lua_poll.c"
307+
fi
308+
309+
if echo "$EVENT_MODULES" | grep ngx_kqueue_module 2>&1 >/dev/null; then
310+
HTTP_LUA_SRCS="$HTTP_LUA_SRCS $ngx_addon_dir/src/event/ngx_http_lua_kqueue.c"
311+
fi
312+
301313
HTTP_LUA_DEPS=" \
302314
$ngx_addon_dir/src/ddebug.h \
303315
$ngx_addon_dir/src/ngx_http_lua_autoconf.h \
@@ -355,6 +367,7 @@ HTTP_LUA_DEPS=" \
355367
$ngx_addon_dir/src/ngx_http_lua_log_ringbuf.h \
356368
$ngx_addon_dir/src/ngx_http_lua_input_filters.h \
357369
$ngx_addon_dir/src/ngx_http_lua_pipe.h \
370+
$ngx_addon_dir/src/ngx_http_lua_event.h \
358371
"
359372

360373
# ----------------------------------------

src/event/ngx_http_lua_epoll.c

+163
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
2+
/*
3+
* Copyright (C) Yichun Zhang (agentzh)
4+
*/
5+
6+
7+
#include <ngx_core.h>
8+
#include <ngx_event.h>
9+
#include <ngx_http.h>
10+
#include "../ngx_http_lua_event.h"
11+
12+
13+
static ngx_int_t ngx_http_lua_epoll_init_event(ngx_cycle_t *cycle);
14+
static ngx_int_t ngx_http_lua_epoll_set_event(ngx_event_t *ev, ngx_int_t event);
15+
static ngx_int_t ngx_http_lua_epoll_process_events(ngx_http_request_t *r,
16+
ngx_msec_t timer);
17+
18+
static int ep = -1;
19+
static struct epoll_event event_list[1];
20+
21+
ngx_http_lua_event_actions_t ngx_http_lua_epoll = {
22+
ngx_http_lua_epoll_init_event,
23+
ngx_http_lua_epoll_set_event,
24+
ngx_http_lua_epoll_process_events,
25+
};
26+
27+
28+
static ngx_int_t
29+
ngx_http_lua_epoll_init_event(ngx_cycle_t *cycle)
30+
{
31+
ep = epoll_create(1);
32+
33+
if (ep == -1) {
34+
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
35+
"epoll_create() failed");
36+
37+
return NGX_ERROR;
38+
}
39+
40+
return NGX_OK;
41+
}
42+
43+
44+
static ngx_int_t
45+
ngx_http_lua_epoll_set_event(ngx_event_t *ev, ngx_int_t event)
46+
{
47+
int op;
48+
uint32_t events, prev;
49+
ngx_event_t *e;
50+
ngx_connection_t *c;
51+
struct epoll_event ee;
52+
53+
c = ev->data;
54+
55+
events = (uint32_t) event;
56+
57+
if (event == NGX_READ_EVENT) {
58+
e = c->write;
59+
prev = EPOLLOUT;
60+
#if (NGX_READ_EVENT != EPOLLIN|EPOLLRDHUP)
61+
events = EPOLLIN|EPOLLRDHUP;
62+
#endif
63+
64+
} else {
65+
e = c->read;
66+
prev = EPOLLIN|EPOLLRDHUP;
67+
#if (NGX_WRITE_EVENT != EPOLLOUT)
68+
events = EPOLLOUT;
69+
#endif
70+
}
71+
72+
if (e->active) {
73+
op = EPOLL_CTL_MOD;
74+
events |= prev;
75+
76+
} else {
77+
op = EPOLL_CTL_ADD;
78+
}
79+
80+
ee.events = events;
81+
ee.data.ptr = c;
82+
83+
if (epoll_ctl(ep, op, c->fd, &ee) == -1) {
84+
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
85+
"epoll_ctl(%d, %d) failed", op, c->fd);
86+
87+
return NGX_ERROR;
88+
}
89+
90+
ev->active = 1;
91+
92+
return NGX_OK;
93+
}
94+
95+
96+
static ngx_int_t
97+
ngx_http_lua_epoll_process_events(ngx_http_request_t *r, ngx_msec_t timer)
98+
{
99+
int events;
100+
uint32_t revents;
101+
ngx_err_t err;
102+
ngx_event_t *rev, *wev;
103+
ngx_connection_t *c;
104+
105+
events = epoll_wait(ep, event_list, 1, timer);
106+
107+
err = (events == -1) ? ngx_errno : 0;
108+
109+
if (err) {
110+
ngx_log_error(NGX_LOG_ALERT, r->connection->log, err,
111+
"epoll_wait() failed");
112+
113+
return NGX_ERROR;
114+
}
115+
116+
if (events == 0) {
117+
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
118+
"epoll_wait() returned no events without timeout");
119+
120+
return NGX_ERROR;
121+
}
122+
123+
c = event_list[0].data.ptr;
124+
revents = event_list[0].events;
125+
126+
if (revents & (EPOLLERR|EPOLLHUP)) {
127+
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
128+
"epoll_wait() error on fd:%d ev:%04XD",
129+
c->fd, revents);
130+
131+
/*
132+
* if the error events were returned, add EPOLLIN and EPOLLOUT
133+
* to handle the events at least in one active handler
134+
*/
135+
136+
revents |= EPOLLIN|EPOLLOUT;
137+
}
138+
139+
rev = c->read;
140+
141+
if ((revents & EPOLLIN) && rev->active) {
142+
143+
#if (NGX_HAVE_EPOLLRDHUP)
144+
if (revents & EPOLLRDHUP) {
145+
rev->pending_eof = 1;
146+
}
147+
#endif
148+
149+
rev->ready = 1;
150+
rev->available = -1;
151+
}
152+
153+
wev = c->write;
154+
155+
if ((revents & EPOLLOUT) && wev->active) {
156+
wev->ready = 1;
157+
#if (NGX_THREADS)
158+
wev->complete = 1;
159+
#endif
160+
}
161+
162+
return NGX_OK;
163+
}

src/event/ngx_http_lua_kqueue.c

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
2+
/*
3+
* Copyright (C) Yichun Zhang (agentzh)
4+
*/
5+
6+
7+
#include <ngx_core.h>
8+
#include <ngx_event.h>
9+
#include <ngx_http.h>
10+
#include "../ngx_http_lua_event.h"
11+
12+
13+
static ngx_int_t ngx_http_lua_kqueue_init_event(ngx_cycle_t *cycle);
14+
static ngx_int_t ngx_http_lua_kqueue_set_event(ngx_event_t *ev,
15+
ngx_int_t event);
16+
static ngx_int_t ngx_http_lua_kqueue_process_events(ngx_http_request_t *r,
17+
ngx_msec_t timer);
18+
19+
int ngx_lua_kqueue = -1;
20+
static struct kevent change_list[1];
21+
static struct kevent event_list[1];
22+
23+
ngx_http_lua_event_actions_t ngx_http_lua_kqueue = {
24+
ngx_http_lua_kqueue_init_event,
25+
ngx_http_lua_kqueue_set_event,
26+
ngx_http_lua_kqueue_process_events,
27+
};
28+
29+
30+
static ngx_int_t
31+
ngx_http_lua_kqueue_init_event(ngx_cycle_t *cycle)
32+
{
33+
if (ngx_lua_kqueue == -1) {
34+
ngx_lua_kqueue = kqueue();
35+
36+
if (ngx_lua_kqueue == -1) {
37+
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
38+
"kqueue() failed");
39+
40+
return NGX_ERROR;
41+
}
42+
}
43+
44+
return NGX_OK;
45+
}
46+
47+
48+
static ngx_int_t
49+
ngx_http_lua_kqueue_set_event(ngx_event_t *ev, ngx_int_t event)
50+
{
51+
struct kevent *kev;
52+
ngx_connection_t *c;
53+
54+
c = ev->data;
55+
56+
ev->active = 1;
57+
58+
kev = &change_list[0];
59+
60+
kev->ident = c->fd;
61+
kev->filter = (short) event;
62+
kev->flags = EV_ADD|EV_ENABLE;
63+
kev->udata = NGX_KQUEUE_UDATA_T ((uintptr_t) ev | ev->instance);
64+
65+
return NGX_OK;
66+
}
67+
68+
69+
static ngx_int_t
70+
ngx_http_lua_kqueue_process_events(ngx_http_request_t *r, ngx_msec_t timer)
71+
{
72+
int events;
73+
struct timespec ts;
74+
ngx_event_t *ev;
75+
ngx_int_t instance;
76+
ngx_err_t err;
77+
78+
ts.tv_sec = timer / 1000;
79+
ts.tv_nsec = (timer % 1000) * 1000000;
80+
81+
events = kevent(ngx_lua_kqueue, change_list, 1, event_list, 1, &ts);
82+
83+
err = (events == -1) ? ngx_errno : 0;
84+
85+
if (err) {
86+
ngx_log_error(NGX_LOG_ALERT, r->connection->log, err,
87+
"kevent() failed");
88+
89+
return NGX_ERROR;
90+
}
91+
92+
if (events == 0) {
93+
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
94+
"kevent() returned no events without timeout");
95+
96+
return NGX_ERROR;
97+
}
98+
99+
ev = (ngx_event_t *) event_list[0].udata;
100+
instance = (uintptr_t) ev & 1;
101+
ev = (ngx_event_t *) ((uintptr_t) ev & (uintptr_t) ~1);
102+
103+
ev->available = event_list[0].data;
104+
105+
if (event_list[0].flags & EV_EOF) {
106+
ev->pending_eof = 1;
107+
}
108+
109+
ev->ready = 1;
110+
111+
return NGX_OK;
112+
}

0 commit comments

Comments
 (0)