summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-08-19 05:16:20 +0000
committershugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-08-19 05:16:20 +0000
commit2bd37c71839858341cf2534657a60261e05f275f (patch)
tree713ca63b690755c9afb2129c4bde0823601e3014
parent5852b97e4eb18560b911848095025404926904da (diff)
* lib/net/imap.rb (idle): raises a Net::IMAP::Error when the
connection is closed. based on the patch by Hugo Barauna. [Bug #5190] [ruby-core:38930] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33007 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog6
-rw-r--r--lib/net/imap.rb16
-rw-r--r--test/net/imap/test_imap.rb55
3 files changed, 74 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 1fe2bc2e2c..7641121d5d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Fri Aug 19 14:12:57 2011 Shugo Maeda <shugo@ruby-lang.org>
+
+ * lib/net/imap.rb (idle): raises a Net::IMAP::Error when the
+ connection is closed. based on the patch by Hugo Barauna.
+ [Bug #5190] [ruby-core:38930]
+
Fri Aug 19 13:18:00 2011 Kenta Murata <mrkn@mrkn.jp>
* configure.in: defines _DARWIN_UNLIMITED_SELECT if the target_os
diff --git a/lib/net/imap.rb b/lib/net/imap.rb
index 9095ea399a..eacf0e4cc4 100644
--- a/lib/net/imap.rb
+++ b/lib/net/imap.rb
@@ -905,10 +905,15 @@ module Net
@idle_done_cond = new_cond
@idle_done_cond.wait
@idle_done_cond = nil
+ if @receiver_thread_terminating
+ raise Net::IMAP::Error, "connection closed"
+ end
ensure
- remove_response_handler(response_handler)
- put_string("DONE#{CRLF}")
- response = get_tagged_response(tag, "IDLE")
+ unless @receiver_thread_terminating
+ remove_response_handler(response_handler)
+ put_string("DONE#{CRLF}")
+ response = get_tagged_response(tag, "IDLE")
+ end
end
end
@@ -1056,6 +1061,7 @@ module Net
rescue Exception
end
}
+ @receiver_thread_terminating = false
end
def receive_responses
@@ -1115,8 +1121,12 @@ module Net
end
end
synchronize do
+ @receiver_thread_terminating = true
@tagged_response_arrival.broadcast
@continuation_request_arrival.broadcast
+ if @idle_done_cond
+ @idle_done_cond.signal
+ end
end
end
diff --git a/test/net/imap/test_imap.rb b/test/net/imap/test_imap.rb
index 01982ab815..c67886fed4 100644
--- a/test/net/imap/test_imap.rb
+++ b/test/net/imap/test_imap.rb
@@ -363,6 +363,61 @@ class IMAPTest < Test::Unit::TestCase
end
end
+ def test_connection_closed_during_idle
+ server = create_tcp_server
+ port = server.addr[1]
+ requests = []
+ sock = nil
+ Thread.start do
+ begin
+ sock = server.accept
+ sock.print("* OK test server\r\n")
+ requests.push(sock.gets)
+ sock.print("+ idling\r\n")
+ rescue
+ end
+ end
+ begin
+ imap = Net::IMAP.new(SERVER_ADDR, :port => port)
+ begin
+ th = Thread.current
+ m = Monitor.new
+ in_idle = false
+ exception_raised = false
+ c = m.new_cond
+ Thread.start do
+ m.synchronize do
+ until in_idle
+ c.wait(0.1)
+ end
+ end
+ sock.close
+ exception_raised = true
+ end
+ assert_raise(Net::IMAP::Error) do
+ imap.idle do |res|
+ m.synchronize do
+ in_idle = true
+ c.signal
+ until exception_raised
+ c.wait(0.1)
+ end
+ end
+ end
+ end
+ assert_equal(1, requests.length)
+ assert_equal("RUBY0001 IDLE\r\n", requests[0])
+ ensure
+ imap.disconnect if imap
+ end
+ ensure
+ server.close
+ if sock && !sock.closed?
+ sock.close
+ end
+ end
+ end
+
private
def imaps_test