Skip to content

Commit 836cadf

Browse files
committed
feature: support socket in some not yieldable phase
1 parent fdf752d commit 836cadf

9 files changed

+877
-7
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

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

src/event/ngx_http_lua_kqueue.c

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
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_clear_event(ngx_event_t *ev,
17+
ngx_int_t event);
18+
static ngx_int_t ngx_http_lua_kqueue_process_event(ngx_http_request_t *r,
19+
ngx_msec_t timer);
20+
21+
int kq = -1;
22+
static struct kevent kch;
23+
static struct kevent kev;
24+
25+
ngx_http_lua_event_actions_t ngx_http_lua_kqueue = {
26+
ngx_http_lua_kqueue_init_event,
27+
ngx_http_lua_kqueue_set_event,
28+
ngx_http_lua_kqueue_clear_event,
29+
ngx_http_lua_kqueue_process_event,
30+
};
31+
32+
33+
static ngx_int_t
34+
ngx_http_lua_kqueue_init_event(ngx_cycle_t *cycle)
35+
{
36+
kq = kqueue();
37+
38+
if (kq == -1) {
39+
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
40+
"lua kqueue() failed");
41+
42+
return NGX_ERROR;
43+
}
44+
45+
return NGX_OK;
46+
}
47+
48+
49+
static ngx_int_t
50+
ngx_http_lua_kqueue_set_event(ngx_event_t *ev, ngx_int_t event)
51+
{
52+
ngx_connection_t *c;
53+
54+
c = ev->data;
55+
56+
ev->active = 1;
57+
58+
kch.ident = c->fd;
59+
kch.filter = (short) event;
60+
kch.flags = EV_ADD|EV_ENABLE;
61+
kch.udata = NGX_KQUEUE_UDATA_T (ev);
62+
63+
return NGX_OK;
64+
}
65+
66+
67+
static ngx_int_t
68+
ngx_http_lua_kqueue_clear_event(ngx_event_t *ev, ngx_int_t event)
69+
{
70+
ngx_connection_t *c;
71+
72+
c = ev->data;
73+
74+
ev->active = 0;
75+
76+
kch.ident = c->fd;
77+
kch.filter = (short) event;
78+
kch.flags = EV_DELETE;
79+
kch.udata = NGX_KQUEUE_UDATA_T (ev);
80+
81+
if (kevent(kq, &kch, 1, NULL, 0, NULL) == -1) {
82+
ngx_log_error(NGX_LOG_ALERT, r->connection->log, err,
83+
"lua kevent() failed");
84+
85+
return NGX_ERROR;
86+
}
87+
88+
return NGX_OK;
89+
}
90+
91+
92+
static ngx_int_t
93+
ngx_http_lua_kqueue_process_event(ngx_http_request_t *r, ngx_msec_t timer)
94+
{
95+
int events;
96+
struct timespec ts;
97+
ngx_event_t *ev;
98+
ngx_err_t err;
99+
100+
ts.tv_sec = timer / 1000;
101+
ts.tv_nsec = (timer % 1000) * 1000000;
102+
103+
events = kevent(kq, &kch, 1, &kev, 1, &ts);
104+
105+
err = (events == -1) ? ngx_errno : 0;
106+
107+
if (err) {
108+
ngx_log_error(NGX_LOG_ALERT, r->connection->log, err,
109+
"lua kevent() failed");
110+
111+
return NGX_ERROR;
112+
}
113+
114+
if (events == 0) {
115+
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
116+
"lua kevent() returned no events without timeout");
117+
118+
return NGX_ERROR;
119+
}
120+
121+
ev = (ngx_event_t *) kev.udata;
122+
123+
ev->available = kev.data;
124+
ev->ready = 1;
125+
126+
if (kev.flags & EV_EOF) {
127+
ev->pending_eof = 1;
128+
}
129+
130+
return NGX_OK;
131+
}

0 commit comments

Comments
 (0)