ry / ebb fork watch download tarball
public this repo is viewable by everyone
Description: web server
Homepage: http://ebb.rubyforge.org
Clone URL: git://github.com/ry/ebb.git
Allow for threads outside of ebb to run.

uses rb_thread_select() but this is not the typical case - should still be 
fast for normal case
Ryan Dahl (author)
2 months ago
commit  03904ad050dfa2ff8814b28debc95f1020d2a58f
tree    79ec970defc21422d64f3c8383b603ae905322f2
parent  49fe3951f6168ca7cd3f828080aa67aaffeef187
...
40
41
42
43
 
44
45
46
...
49
50
51
52
 
53
54
55
56
57
 
 
 
 
 
 
 
 
58
59
60
...
72
73
74
75
76
77
 
78
 
 
 
 
 
 
 
 
 
 
 
 
 
79
80
81
...
273
274
275
 
 
276
277
278
...
40
41
42
 
43
44
45
46
...
49
50
51
 
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
...
80
81
82
 
 
 
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
...
292
293
294
295
296
297
298
299
0
@@ -40,7 +40,7 @@ struct ev_idle idle_watcher;
0
 # define RSTRING_LEN(s) (RSTRING(s)->len)
0
 #endif
0
 
0
-void attach_idle_watcher()
0
+static void attach_idle_watcher()
0
 {
0
   if(!ev_is_active(&idle_watcher)) {
0
     ev_idle_start (loop, &idle_watcher);
0
@@ -49,12 +49,20 @@ void attach_idle_watcher()
0
 }
0
 
0
 
0
-void detach_idle_watcher()
0
+static void detach_idle_watcher()
0
 {
0
   ev_idle_stop(loop, &idle_watcher);
0
   printf("detach!\n");
0
 }
0
 
0
+static int clients_in_use_p()
0
+{
0
+ int i;
0
+ for(i = 0; i < EBB_MAX_CLIENTS; i++)
0
+ if(server->clients[i].in_use) return TRUE;
0
+ return FALSE;
0
+}
0
+
0
 void request_cb(ebb_client *client, void *data)
0
 {
0
   VALUE waiting_clients = (VALUE)data;
0
@@ -72,10 +80,21 @@ VALUE server_listen_on_port(VALUE _, VALUE port)
0
 
0
 static void
0
 idle_cb (struct ev_loop *loop, struct ev_idle *w, int revents) {
0
- if(rb_thread_alone()) {
0
- detach_idle_watcher();
0
- } else {
0
+ if(clients_in_use_p()) {
0
     rb_thread_schedule();
0
+ } else if(!rb_thread_alone()) {
0
+ /* if you have another long running thread running besides the ones used
0
+ * for the webapp's requests you will run into performance problems in
0
+ * ruby 1.8.x because rb_thread_select is slow.
0
+ * (Don't worry - you're probably not doing this.)
0
+ */
0
+ struct timeval tv = { tv_sec: 0, tv_usec: 50000 };
0
+ fd_set server_fd_set;
0
+ FD_ZERO(&server_fd_set);
0
+ FD_SET(server->fd, &server_fd_set);
0
+ rb_thread_select(server->fd+1, &server_fd_set, 0, 0, &tv);
0
+ } else {
0
+ detach_idle_watcher();
0
   }
0
 }
0
 
0
@@ -273,6 +292,8 @@ void Init_ebb_ext()
0
   loop = ev_default_loop (0);
0
   
0
   ev_idle_init (&idle_watcher, idle_cb);
0
+ attach_idle_watcher();
0
+
0
   server = ebb_server_alloc();
0
   VALUE waiting_clients = rb_ary_new();
0
   rb_iv_set(mFFI, "@waiting_clients", waiting_clients);

Comments

    No one has commented yet.