0
static VALUE global_http_prefix;
0
@@ -29,6 +31,10 @@ static VALUE global_http_host;
0
static ebb_server *server;
0
+static pthread_mutex_t waiting_clients_lock = PTHREAD_MUTEX_INITIALIZER;
0
+static GQueue *waiting_clients;
0
/* Variables with a leading underscore are C-level variables */
0
@@ -38,39 +44,60 @@ struct ev_loop *loop;
0
# define RSTRING_LEN(s) (RSTRING(s)->len)
0
-void request_cb(ebb_client *client, void *data)
0
+void request_cb(ebb_client *client, void *_)
0
- VALUE waiting_clients = (VALUE)data;
0
- VALUE rb_client = Data_Wrap_Struct(cClient, 0, 0, client);
0
- rb_ary_push(waiting_clients, rb_client);
0
-VALUE server_listen_on_port(VALUE _, VALUE port)
0
- if(ebb_server_listen_on_port(server, FIX2INT(port)) < 0)
0
- rb_sys_fail("Problem listening on port");
0
+ pthread_mutex_lock(&waiting_clients_lock);
0
+ g_queue_push_tail(waiting_clients, (void*)client);
0
+ pthread_mutex_unlock(&waiting_clients_lock);
0
+ assert(notify_fd > 2);
0
+ assert(1 == write(notify_fd, "N", 1));
0
oneshot_timeout (struct ev_loop *loop, struct ev_timer *w, int revents) {;}
0
-VALUE server_process_connections(VALUE _)
0
+static void* process_connections(void *_)
0
+VALUE server_next_client(VALUE _)
0
- ev_timer_init (&timeout, oneshot_timeout, 0.01, 0.);
0
- ev_timer_start (loop, &timeout);
0
- ev_loop(loop, EVLOOP_ONESHOT);
0
- /* XXX: Need way to know when the loop is finished...
0
- * should return true or false */
0
- ev_timer_stop(loop, &timeout);
0
+ pthread_mutex_lock(&waiting_clients_lock);
0
+ client = g_queue_pop_head(waiting_clients);
0
+ pthread_mutex_unlock(&waiting_clients_lock);
0
+ rb_client = Data_Wrap_Struct(cClient, 0, 0, client);
0
+VALUE server_listen_on_port(VALUE _, VALUE port)
0
+ if(ebb_server_listen_on_port(server, FIX2INT(port)) < 0)
0
+ rb_sys_fail("Problem listening on port");
0
+ assert(0 <= pipe(fildes));
0
+ /* the read side is blocking */
0
+ int flags = fcntl(fildes[0], F_GETFL, 0);
0
+ assert(0 <= fcntl(fildes[0], F_SETFL, flags & ~O_NONBLOCK));
0
+ /* the write side is nonblocking */
0
+ flags = fcntl(fildes[1], F_GETFL, 0);
0
+ assert(0 <= fcntl(fildes[1], F_SETFL, flags | O_NONBLOCK));
0
+ notify_fd = fildes[1];
0
+ assert(0 <= pthread_create(&thread, NULL, process_connections, NULL));
0
+ pthread_detach(thread);
0
+ return INT2FIX(fildes[0]);
0
@@ -215,8 +242,9 @@ void Init_ebb_ext()
0
DEF_GLOBAL(path_info, "PATH_INFO");
0
DEF_GLOBAL(content_length, "CONTENT_LENGTH");
0
DEF_GLOBAL(http_host, "HTTP_HOST");
0
+ rb_define_singleton_method(mFFI, "server_next_client", server_next_client, 0);
0
- rb_define_singleton_method(mFFI, "server_process_connections", server_process_connections, 0);
0
rb_define_singleton_method(mFFI, "server_listen_on_port", server_listen_on_port, 1);
0
rb_define_singleton_method(mFFI, "server_unlisten", server_unlisten, 0);
0
@@ -231,7 +259,8 @@ void Init_ebb_ext()
0
/* initialize ebb_server */
0
loop = ev_default_loop (0);
0
server = ebb_server_alloc();
0
- VALUE waiting_clients = rb_ary_new();
0
- rb_iv_set(mFFI, "@waiting_clients", waiting_clients);
0
- ebb_server_init(server, loop, request_cb, (void*)waiting_clients);
0
+ waiting_clients = g_queue_new();
0
+ ebb_server_init(server, loop, request_cb, NULL);
Comments
No one has commented yet.