Skip to content

Commit d171684

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

6 files changed

+383
-5
lines changed

config

+3
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,8 @@ HTTP_LUA_SRCS=" \
296296
$ngx_addon_dir/src/ngx_http_lua_log_ringbuf.c \
297297
$ngx_addon_dir/src/ngx_http_lua_input_filters.c \
298298
$ngx_addon_dir/src/ngx_http_lua_pipe.c \
299+
$ngx_addon_dir/src/event/ngx_http_lua_kqueue.c \
300+
$ngx_addon_dir/src/event/ngx_http_lua_poll.c \
299301
"
300302

301303
HTTP_LUA_DEPS=" \
@@ -355,6 +357,7 @@ HTTP_LUA_DEPS=" \
355357
$ngx_addon_dir/src/ngx_http_lua_log_ringbuf.h \
356358
$ngx_addon_dir/src/ngx_http_lua_input_filters.h \
357359
$ngx_addon_dir/src/ngx_http_lua_pipe.h \
360+
$ngx_addon_dir/src/ngx_http_lua_event.h \
358361
"
359362

360363
# ----------------------------------------

src/event/ngx_http_lua_kqueue.c

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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+
11+
int ngx_lua_kqueue = -1;
12+
static struct kevent change_list[1];
13+
static struct kevent event_list[1];
14+
15+
ngx_int_t
16+
ngx_http_lua_kqueue_init(ngx_conf_t *cf)
17+
{
18+
if (ngx_lua_kqueue == -1) {
19+
ngx_lua_kqueue = kqueue();
20+
21+
if (ngx_lua_kqueue == -1) {
22+
ngx_conf_log_error(NGX_LOG_ALERT, cf, 0, "kqueue() failed");
23+
24+
return NGX_ERROR;
25+
}
26+
}
27+
28+
return NGX_OK;
29+
}
30+
31+
32+
void
33+
ngx_http_lua_kqueue_set_event(ngx_event_t *ev, ngx_int_t event)
34+
{
35+
struct kevent *kev;
36+
ngx_connection_t *c;
37+
38+
c = ev->data;
39+
40+
ev->active = 1;
41+
42+
kev = &change_list[0];
43+
44+
kev->ident = c->fd;
45+
kev->filter = (short) event;
46+
kev->flags = EV_ADD|EV_ENABLE;
47+
kev->udata = NGX_KQUEUE_UDATA_T ((uintptr_t) ev | ev->instance);
48+
}
49+
50+
51+
ngx_int_t
52+
ngx_http_lua_kqueue_process_events(ngx_http_request_t *r, ngx_msec_t timer)
53+
{
54+
int events;
55+
struct timespec ts;
56+
ngx_event_t *ev;
57+
ngx_int_t instance;
58+
ngx_err_t err;
59+
60+
ts.tv_sec = timer / 1000;
61+
ts.tv_nsec = (timer % 1000) * 1000000;
62+
63+
events = kevent(ngx_lua_kqueue, change_list, 1, event_list, 1, &ts);
64+
65+
err = (events == -1) ? ngx_errno : 0;
66+
67+
if (err) {
68+
ngx_log_error(NGX_LOG_ALERT, r->connection->log, err, "kevent() failed");
69+
70+
return NGX_ERROR;
71+
}
72+
73+
if (events == 0) {
74+
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
75+
"kevent() returned no events without timeout");
76+
77+
return NGX_ERROR;
78+
}
79+
80+
ev = (ngx_event_t *) event_list[0].udata;
81+
instance = (uintptr_t) ev & 1;
82+
ev = (ngx_event_t *) ((uintptr_t) ev & (uintptr_t) ~1);
83+
84+
ev->available = event_list[0].data;
85+
ev->ready = 1;
86+
87+
return NGX_OK;
88+
}

src/event/ngx_http_lua_poll.c

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
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+
11+
static struct pollfd event_list[1];
12+
13+
ngx_int_t
14+
ngx_http_lua_poll_init(ngx_conf_t *cf)
15+
{
16+
return NGX_OK;
17+
}
18+
19+
20+
void
21+
ngx_http_lua_poll_set_event(ngx_event_t *ev, ngx_int_t event)
22+
{
23+
ngx_connection_t *c;
24+
25+
c = ev->data;
26+
27+
ev->active = 1;
28+
29+
if (event == NGX_READ_EVENT) {
30+
#if (NGX_READ_EVENT != POLLIN)
31+
event = POLLIN;
32+
#endif
33+
34+
} else {
35+
#if (NGX_WRITE_EVENT != POLLOUT)
36+
event = POLLOUT;
37+
#endif
38+
}
39+
40+
event_list[0].fd = c->fd;
41+
event_list[0].events = (short) event;
42+
event_list[0].revents = 0;
43+
}
44+
45+
46+
ngx_int_t
47+
ngx_http_lua_poll_process_events(ngx_http_request_t *r, ngx_msec_t timer)
48+
{
49+
int ready, revents;
50+
ngx_event_t *ev;
51+
ngx_err_t err;
52+
ngx_connection_t *c;
53+
54+
ready = poll(event_list, 1, (int) timer);
55+
56+
err = (ready == -1) ? ngx_errno : 0;
57+
58+
if (err) {
59+
ngx_log_error(NGX_LOG_ALERT, r->connection->log, err, "poll() failed");
60+
61+
return NGX_ERROR;
62+
}
63+
64+
if (ready == 0) {
65+
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
66+
"poll() returned no events without timeout");
67+
68+
return NGX_ERROR;
69+
}
70+
71+
revents = event_list[0].revents;
72+
c = ngx_cycle->files[event_list[0].fd];
73+
74+
if ((revents & POLLIN) && c->read->active) {
75+
ev = c->read;
76+
ev->ready = 1;
77+
ev->available = -1;
78+
}
79+
80+
if ((revents & POLLOUT) && c->write->active) {
81+
ev = c->write;
82+
ev->ready = 1;
83+
}
84+
85+
return NGX_OK;
86+
}

src/ngx_http_lua_event.h

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
2+
/*
3+
* Copyright (C) Yichun Zhang (agentzh)
4+
*/
5+
6+
7+
#ifndef _NGX_HTTP_LUA_EVENT_H_INCLUDED_
8+
#define _NGX_HTTP_LUA_EVENT_H_INCLUDED_
9+
10+
11+
#include "ngx_http_lua_common.h"
12+
13+
14+
ngx_int_t ngx_http_lua_poll_init(ngx_conf_t *cf);
15+
16+
void ngx_http_lua_poll_set_event(ngx_event_t *ev, ngx_int_t event);
17+
18+
ngx_int_t ngx_http_lua_poll_process_events(ngx_http_request_t *r,
19+
ngx_msec_t timer);
20+
21+
ngx_int_t ngx_http_lua_kqueue_init(ngx_conf_t *cf);
22+
23+
void ngx_http_lua_kqueue_set_event(ngx_event_t *ev, ngx_int_t event);
24+
25+
ngx_int_t ngx_http_lua_kqueue_process_events(ngx_http_request_t *r,
26+
ngx_msec_t timer);
27+
28+
29+
#define ngx_http_lua_init_event ngx_http_lua_poll_init
30+
#define ngx_http_lua_set_event ngx_http_lua_poll_set_event
31+
#define ngx_http_lua_process_events ngx_http_lua_poll_process_events
32+
33+
34+
#endif /* _NGX_HTTP_LUA_EVENT_H_INCLUDED_ */
35+
36+
/* vi:set ft=c ts=4 sw=4 et fdm=marker: */

src/ngx_http_lua_module.c

+6
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "ngx_http_lua_ssl_session_fetchby.h"
3232
#include "ngx_http_lua_headers.h"
3333
#include "ngx_http_lua_pipe.h"
34+
#include "ngx_http_lua_event.h"
3435

3536

3637
static void *ngx_http_lua_create_main_conf(ngx_conf_t *cf);
@@ -786,6 +787,11 @@ ngx_http_lua_init(ngx_conf_t *cf)
786787
cln->handler = ngx_http_lua_ngx_raw_header_cleanup;
787788
#endif
788789

790+
rc = ngx_http_lua_init_event(cf);
791+
if (rc == NGX_ERROR) {
792+
return rc;
793+
}
794+
789795
if (lmcf->lua == NULL) {
790796
dd("initializing lua vm");
791797

0 commit comments

Comments
 (0)