ry / ebb fork watch download tarball
public
Description: web server
Homepage: http://ebb.rubyforge.org
Clone URL: git://github.com/ry/ebb.git
Search Repo:
Add comments to ebb_ruby.c:idle_cb
ryah (author)
Sun Apr 06 08:32:17 -0700 2008
commit  4c0d9bb92866164e71e922b17f1591f6611a61e0
tree    f18166092779f2c953aaadd400df012922c016ec
parent  7bfe53508a2139735c8641bfe57cbc2317b7c3cd
...
85
86
87
 
 
88
89
 
 
 
 
 
 
90
 
 
 
 
 
91
 
92
93
94
95
96
 
 
 
 
 
97
98
99
100
101
102
 
103
 
 
 
 
 
104
105
106
...
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
 
 
 
 
107
108
109
110
111
112
 
113
114
115
 
116
117
118
119
120
121
122
123
124
125
0
@@ -85,22 +85,41 @@
0
   return Qnil;
0
 }
0
 
0
+const struct timeval idle_timeout = { tv_sec: 0, tv_usec: 50000 };
0
+
0
 static void
0
 idle_cb (struct ev_loop *loop, struct ev_idle *w, int revents) {
0
+ /* How to let other Ruby threads run while we're in this blocking C call */
0
+
0
+ /* TODO: For Ruby 1.9 I should use rb_thread_blocking_region() instead of
0
+ * this hacky idle_cb
0
+ */
0
+
0
   if(clients_in_use_p()) {
0
+ /* If ruby has control of any clients - that means there are some requests
0
+ * still being processed inside of threads. We need to allow Ruby some
0
+ * time to work on these threads so we call rb_thread_schedule()
0
+ * I don't use rb_thread_select() here because it is very slow.
0
+ */
0
     rb_thread_schedule();
0
+
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
+ /* If no clients are in use, but there are still other Ruby threads then
0
+ * some other thread is running in the Ruby VM which is not a request.
0
+ * This is a sub-optimal situation and we solve it by calling
0
+ * rb_thread_select() to wait for the server fd to wake up.
0
+ * One should try to avoid entering this state.
0
      */
0
- struct timeval select_timeout = { 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, &select_timeout);
0
+ rb_thread_select(server->fd+1, &server_fd_set, 0, 0, &idle_timeout);
0
   } else {
0
+ /* Otherwise there are no other threads. We can detach the idle_watcher
0
+ * and allow the server_process_connections() to block until the
0
+ * server fd wakes up. Because we don't use rb_thread_select() this
0
+ * is quite fast.
0
+ */
0
     detach_idle_watcher();
0
   }
0
 }

Comments

    No one has commented yet.