234 log_ereport(LOG_FAILURE, "sessionhandler: request timeout: cannot remove poll"); |
234 log_ereport(LOG_FAILURE, "sessionhandler: request timeout: cannot remove poll"); |
235 } |
235 } |
236 evt_request_error(h, io->io_event); |
236 evt_request_error(h, io->io_event); |
237 } |
237 } |
238 |
238 |
239 int evt_add_request_timeout(EventHandler *h, Event *event) { |
239 int evt_add_request(EventHandler *h, Event *event) { |
240 EventHttpIO *io = event->cookie; |
240 EventHttpIO *io = event->cookie; |
241 io->watch.intdata = 1; |
241 Connection *conn = io->request->connection; |
242 ev_watchlist_add(h, &io->watch); |
242 |
|
243 if(ev_pollin(h, conn->fd, io->io_event) != 0) { |
|
244 // TODO: ev_pollin should log, intercept some errors here |
|
245 log_ereport(LOG_FAILURE, "Cannot enqueue connection"); |
|
246 evt_request_error(h, event); |
|
247 } else { |
|
248 // add request timeout |
|
249 io->watch.intdata = 1; |
|
250 io->watch.created = time(NULL); |
|
251 io->watch.expire = io->watch.created + 240; // TODO: config |
|
252 io->watch.destroy = evt_request_timeout; |
|
253 io->watch.data1 = io; |
|
254 ev_watchlist_add(h, &io->watch); |
|
255 } |
|
256 |
243 return 0; |
257 return 0; |
244 } |
258 } |
245 |
259 |
246 void evt_enq_conn(SessionHandler *handler, Connection *conn) { |
260 void evt_enq_conn(SessionHandler *handler, Connection *conn) { |
|
261 Event *start_request = malloc(sizeof(Event)); |
|
262 if(!start_request) { |
|
263 connection_destroy(conn); |
|
264 return; |
|
265 } |
|
266 |
247 Event *event = malloc(sizeof(Event)); |
267 Event *event = malloc(sizeof(Event)); |
248 if(!event) { |
268 if(!event) { |
249 connection_destroy(conn); |
269 connection_destroy(conn); |
|
270 free(start_request); |
250 return; |
271 return; |
251 } |
272 } |
252 |
273 |
253 EventHttpIO *io = evt_req_init(handler, conn); |
274 EventHttpIO *io = evt_req_init(handler, conn); |
254 if(!io) { |
275 if(!io) { |
255 connection_destroy(conn); |
276 connection_destroy(conn); |
|
277 free(start_request); |
256 free(event); |
278 free(event); |
257 return; |
279 return; |
258 } |
280 } |
259 |
|
260 /* |
|
261 * to start the request handling, we begin with a poll on the socket, |
|
262 * |
|
263 * evt_enq_conn() --> event handler --> handle_request() |
|
264 */ |
|
265 |
281 |
266 ZERO(event, sizeof(Event)); |
282 ZERO(event, sizeof(Event)); |
267 event->fn = conn->ssl && !conn->ssl_accepted ? evt_request_ssl_accept : evt_request_input; |
283 event->fn = conn->ssl && !conn->ssl_accepted ? evt_request_ssl_accept : evt_request_input; |
268 event->finish = evt_request_finish; |
284 event->finish = evt_request_finish; |
269 event->cookie = io; |
285 event->cookie = io; |
270 io->io_event = event; |
286 io->io_event = event; |
271 |
287 |
|
288 /* |
|
289 * to start the request handling, switch to the event handler |
|
290 * |
|
291 * evt_enq_conn() --> event handler --> handle_request() |
|
292 */ |
|
293 |
272 EventHandler *ev = ev_instance(((EventSessionHandler*)handler)->eventhandler); |
294 EventHandler *ev = ev_instance(((EventSessionHandler*)handler)->eventhandler); |
273 |
295 |
274 if(ev_pollin(ev, conn->fd, event) != 0) { |
296 ZERO(start_request, sizeof(Event)); |
275 // TODO: ev_pollin should log, intercept some errors here |
297 start_request->cookie = io; |
276 log_ereport(LOG_FAILURE, "Cannot enqueue connection"); |
298 start_request->fn = evt_add_request; |
|
299 start_request->finish = ev_free_event; |
|
300 start_request->error = 0; |
|
301 if(event_send(ev, start_request)) { |
|
302 log_ereport(LOG_FAILURE, "Cannot start request timeout: event_send failed"); |
277 evt_request_error(ev, event); |
303 evt_request_error(ev, event); |
278 } else { |
304 free(start_request); |
279 // add request timeout |
|
280 io->watch.created = time(NULL); |
|
281 io->watch.expire = io->watch.created + 240; // TODO: config |
|
282 io->watch.destroy = evt_request_timeout; |
|
283 io->watch.data1 = io; |
|
284 |
|
285 Event *add_timeout = malloc(sizeof(Event)); |
|
286 if(add_timeout) { |
|
287 add_timeout->cookie = io; |
|
288 add_timeout->fn = evt_add_request_timeout; |
|
289 add_timeout->finish = ev_free_event; |
|
290 add_timeout->error = 0; |
|
291 if(event_send(ev, add_timeout)) { |
|
292 log_ereport(LOG_FAILURE, "Cannot add request timeout: event_send failed"); |
|
293 } |
|
294 } else { |
|
295 // not an error that breaks everything, a log message is enough |
|
296 log_ereport(LOG_FAILURE, "Cannot add request timeout: OOM"); |
|
297 } |
|
298 } |
305 } |
299 } |
306 } |
300 |
307 |
301 EventHttpIO* evt_req_init(SessionHandler *handler, Connection *conn) { |
308 EventHttpIO* evt_req_init(SessionHandler *handler, Connection *conn) { |
302 // set socket non blocking |
309 // set socket non blocking |