12
12
13
13
#include <math.h> /* HUGE_VAL */
14
14
#include <stdlib.h> /* calloc, free */
15
+ #include <poll.h> /* POLLIN, POLLOUT */
15
16
16
17
#include <lua.h>
17
18
#include <lauxlib.h>
@@ -100,14 +101,23 @@ static void ngx_http_lua_fd_cleanup(ngx_http_lua_co_ctx_t *co_ctx) {
100
101
#endif
101
102
#if defined(nginx_version ) && nginx_version >= 1007005
102
103
if (u -> conn -> read -> posted ) {
104
+ ngx_delete_posted_event (u -> conn -> read );
105
+ }
106
+ if (u -> conn -> write -> posted ) {
107
+ ngx_delete_posted_event (u -> conn -> write );
108
+ }
103
109
#else
104
110
if (u -> conn -> read -> prev ) {
105
- #endif
106
111
ngx_delete_posted_event (u -> conn -> read );
107
112
}
113
+ if (u -> conn -> write -> posted ) {
114
+ ngx_delete_posted_event (u -> conn -> write );
115
+ }
116
+ #endif
108
117
#if (NGX_THREADS )
109
118
ngx_unlock (& u -> conn -> lock );
110
119
u -> conn -> read -> locked = 0 ;
120
+ u -> conn -> write -> locked = 0 ;
111
121
112
122
ngx_mutex_unlock (ngx_posted_events_mutex );
113
123
#endif
@@ -132,8 +142,17 @@ static int ngx_http_lua_fd_wait(lua_State *L) {
132
142
ngx_http_lua_udata_t * u ;
133
143
134
144
ngx_socket_t fd = luaL_optint (L , 1 , -1 ); /* -1 is invalid fd */
135
- double timeout = luaL_optnumber (L , 2 , HUGE_VAL ); /* default to infinite timeout */
136
- if (fd < 0 && timeout == HUGE_VAL ) {
145
+ const char * events = luaL_optstring (L , 2 , "" );
146
+ int poll_mask = 0 ;
147
+ double timeout = luaL_optnumber (L , 3 , HUGE_VAL ); /* default to infinite timeout */
148
+ while (* events ) {
149
+ if (* events == 'r' )
150
+ poll_mask |= POLLIN ;
151
+ else if (* events == 'w' )
152
+ poll_mask |= POLLOUT ;
153
+ events ++ ;
154
+ }
155
+ if ((fd < 0 || !poll_mask ) && timeout == HUGE_VAL ) {
137
156
return luaL_error (L , "must provide a valid file descriptor or timeout" );
138
157
}
139
158
if ((r = ngx_http_lua_get_req (L )) == NULL ) {
@@ -158,10 +177,18 @@ static int ngx_http_lua_fd_wait(lua_State *L) {
158
177
u -> conn -> data = u ;
159
178
u -> conn -> read -> handler = ngx_http_lua_fd_rev_handler ;
160
179
u -> conn -> read -> log = u -> conn -> log ;
180
+ u -> conn -> write -> handler = ngx_http_lua_fd_rev_handler ;
181
+ u -> conn -> write -> log = u -> conn -> log ;
161
182
u -> conn -> number = ngx_atomic_fetch_add (ngx_connection_counter , 1 );
162
183
163
184
if (fd >= 0 ) {
164
- if (ngx_handle_read_event (u -> conn -> read , NGX_LEVEL_EVENT ) != NGX_OK ) {
185
+ if ((poll_mask & POLLIN ) && ngx_handle_read_event (u -> conn -> read , NGX_LEVEL_EVENT ) != NGX_OK ) {
186
+ ngx_free_connection (u -> conn );
187
+ free (u );
188
+ return luaL_error (L , "unable to add to nginx main loop" );
189
+ }
190
+ if ((poll_mask & POLLOUT ) && ngx_handle_write_event (u -> conn -> write , NGX_LEVEL_EVENT ) != NGX_OK ) {
191
+ if (poll_mask & POLLIN ) ngx_del_event (u -> conn -> read , NGX_READ_EVENT , 0 );
165
192
ngx_free_connection (u -> conn );
166
193
free (u );
167
194
return luaL_error (L , "unable to add to nginx main loop" );
0 commit comments