diff options
author | Eric Wong <normalperson@yhbt.net> | 2013-01-24 19:47:41 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2013-01-24 19:54:41 +0000 |
commit | 49f70632e2f4a9b84fd4fced7439d0844fed1bbd (patch) | |
tree | 9a037666f98b597b5cecddbe3c266221c1eaae37 | |
parent | ad5ab9fe21d57b78b7c6681bbc0907c934e898b0 (diff) | |
download | rainbows-49f70632e2f4a9b84fd4fced7439d0844fed1bbd.tar.gz |
on_read normally relies on the close checking in on_readable, but on_deferred_write_complete may be called from on_writable instead (bypassing the close check of on_readable). This affects both Epoll and XEpoll users, but only if they were sending responses via body#to_path and triggering on_deferred_write_complete. While we're at it, favor non-recursive want_more instead of calling on_readable recursively in ev_write_responses to prevent stack growth.
-rw-r--r-- | lib/rainbows/epoll/client.rb | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/lib/rainbows/epoll/client.rb b/lib/rainbows/epoll/client.rb index f690d85..d72696b 100644 --- a/lib/rainbows/epoll/client.rb +++ b/lib/rainbows/epoll/client.rb @@ -102,7 +102,19 @@ module Rainbows::Epoll::Client else write_response(status, headers, body, alive) end - on_read(Z) if alive && 0 == @wr_queue.size && 0 != @buf.size + # try to read more if we didn't have to buffer writes + next_request if alive && 0 == @wr_queue.size + end + + def next_request + if 0 == @buf.size + want_more + else + # pipelined request (already in buffer) + on_read(Z) + return if @wr_queue[0] || closed? + close if :close == @state + end end def epoll_run @@ -120,7 +132,7 @@ module Rainbows::Epoll::Client def on_deferred_write_complete :close == @state and return close - 0 == @buf.size ? on_readable : on_read(Z) + next_request end def handle_error(e) |