0
@@ -28,6 +28,7 @@ static VALUE global_http_host;
0
static ebb_server *server;
0
+static unsigned int client_count = 0;
0
/* Variables with a leading underscore are C-level variables */
0
@@ -42,6 +43,7 @@ void request_cb(ebb_client *client, void *data)
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
@@ -51,46 +53,35 @@ VALUE server_listen_on_port(VALUE _, VALUE port)
0
-oneshot_timeout (struct ev_loop *loop, struct ev_timer *w, int revents) {;}
0
+VALUE server_open(VALUE _)
0
+ return server->open ? Qtrue : Qfalse;
0
VALUE server_process_connections(VALUE _)
0
- /* This function is super hacky. The libev loop is called for one iteration
0
- * this means that any pending events are handled. If no events exist then
0
- * the function blocks. We want blocking so that the while loop in ruby
0
- * doesn't race away - however there is a need to continue to process other
0
- * ruby threads which are running. While this function is being called
0
- * other ruby threads cannot execute.
0
- * So we set this timeout event which breaks the block after 0.1 seconds.
0
- * Additionally we make sure that other threads get enough processing time
0
- * by calling rb_thread_schedule() many times.
0
- * Instead we should probably use rb_thread_select on server->fd when no
0
- * clients are in_use? Whatever happens here, one should make sure the
0
- * 'wait' benchmark is running as quickly with Ebb as it does with mongrel.
0
- ev_timer_init (&timeout, oneshot_timeout, 0.1, 0.);
0
- ev_timer_start (loop, &timeout);
0
- ev_loop(loop, EVLOOP_ONESHOT);
0
+ int fd_count = 0, max_fd = 0;
0
+ struct timeval tv = { tv_sec: 0, tv_usec: 500000 };
0
- /* remove the timeout event so that it isn't called immediately the next
0
- * time around (since 0.1 seconds will have passed)
0
- ev_timer_stop(loop, &timeout);
0
+ fd_set fds; FD_ZERO(&fds);
0
- /* Call rb_thread_schedule() proportional to the number of rb threads running */
0
- /* SO HACKY! Anyone have a better way to do this? */
0
- for(i = 0; i < EBB_MAX_CLIENTS; i++)
0
- if(server->clients[i].in_use)
0
+ FD_SET(server->fd, &fds); fd_count++;
0
+ for(i = 0; i < EBB_MAX_CLIENTS; i++) {
0
+ ebb_client *client = &server->clients[i];
0
+ FD_SET(client->fd, &fds); fd_count++;
0
+ if(client->fd > max_fd) max_fd = client->fd;
0
+ unsigned int last_client_count = client_count;
0
+ ev_loop(loop, EVLOOP_NONBLOCK);
0
+ if(last_client_count == client_count) {
0
+ rb_thread_select(max_fd+1, &fds, &fds, &fds, &tv);
0
+ ev_loop(loop, EVLOOP_NONBLOCK);
0
@@ -259,6 +250,7 @@ void Init_ebb_ext()
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
+ rb_define_singleton_method(mFFI, "server_open?", server_open, 0);
0
cClient = rb_define_class_under(mEbb, "Client", rb_cObject);
0
rb_define_singleton_method(mFFI, "client_read_input", client_read_input, 2);
Comments
No one has commented yet.