From 49f70632e2f4a9b84fd4fced7439d0844fed1bbd Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 24 Jan 2013 19:47:41 +0000 Subject: [PATCH] epoll: ensure closing of pipelined clients if required 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. --- lib/rainbows/epoll/client.rb | 16 ++++++++++++++-- 1 file 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) -- 2.11.4.GIT