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);