ext/event.c in nyara-0.0.1.pre.3 vs ext/event.c in nyara-0.0.1.pre.4

- old
+ new

@@ -19,10 +19,11 @@ #define MAX_E 1024 static void loop_body(int fd, int etype); static int qfd; #define MAX_RECEIVE_DATA 65536 +// * 4 static char received_data[MAX_RECEIVE_DATA]; extern http_parser_settings nyara_request_parse_settings; #ifdef HAVE_KQUEUE #include "inc/kqueue.h" @@ -34,10 +35,11 @@ static VALUE watch_request_map; static ID id_not_found; static VALUE sym_term_close; static VALUE sym_writing; static VALUE sym_reading; +static VALUE sym_sleep; static Request* curr_request; static void _set_nonblock(int fd) { int flags; @@ -57,10 +59,13 @@ } static void _handle_request(VALUE request) { Request* p; Data_Get_Struct(request, Request, p); + if (p->sleeping) { + return; + } curr_request = p; // read and parse data // NOTE we don't let http_parser invoke ruby code, because: // 1. so the stack is shallower @@ -113,12 +118,12 @@ nyara_request_term_close(request, true); } else if (state == sym_writing) { // do nothing } else if (state == sym_reading) { // do nothing - } else { - // double value: sleep + } else if (state == sym_sleep) { + // do nothing } } // platform independent, invoked by LOOP_E() static void loop_body(int fd, int etype) { @@ -176,10 +181,38 @@ LOOP_E(); return Qnil; } +static VALUE ext_request_sleep(VALUE _, VALUE request) { + Request* p; + Data_Get_Struct(request, Request, p); + + VALUE* v_fds = RARRAY_PTR(p->watched_fds); + long v_fds_len = RARRAY_LEN(p->watched_fds); + for (long i = 0; i < v_fds_len; i++) { + DEL_E(FIX2INT(v_fds[i])); + } + DEL_E(p->fd); + p->sleeping = true; + return Qnil; +} + +static VALUE ext_request_wakeup(VALUE _, VALUE request) { + // NOTE should not use current_request + Request* p; + Data_Get_Struct(request, Request, p); + + VALUE* v_fds = RARRAY_PTR(p->watched_fds); + long v_fds_len = RARRAY_LEN(p->watched_fds); + for (long i = 0; i < v_fds_len; i++) { + ADD_E(FIX2INT(v_fds[i]), ETYPE_CONNECT); + } + ADD_E(p->fd, ETYPE_HANDLE_REQUEST); + return Qnil; +} + static VALUE ext_set_nonblock(VALUE _, VALUE v_fd) { int fd = FIX2INT(v_fd); _set_nonblock(fd); return Qnil; } @@ -271,12 +304,16 @@ rb_gc_register_mark_object(watch_request_map); id_not_found = rb_intern("not_found"); sym_term_close = ID2SYM(rb_intern("term_close")); sym_writing = ID2SYM(rb_intern("writing")); sym_reading = ID2SYM(rb_intern("reading")); + sym_sleep = ID2SYM(rb_intern("sleep")); rb_define_singleton_method(ext, "init_queue", ext_init_queue, 0); rb_define_singleton_method(ext, "run_queue", ext_run_queue, 1); + + rb_define_singleton_method(ext, "request_sleep", ext_request_sleep, 0); + rb_define_singleton_method(ext, "request_wakeup", ext_request_wakeup, 0); // fd operations rb_define_singleton_method(ext, "set_nonblock", ext_set_nonblock, 1); rb_define_singleton_method(ext, "fd_watch", ext_fd_watch, 1); rb_define_singleton_method(ext, "fd_send", ext_fd_send, 3);