Hi, Martin Povolnwrote: > And we have discovered then when [ruby] client waits for continuation > request response, > it only accepts request for more data and it hangs [infinite wait] when > it gets error code. (snip) > So following patch agains imap.rb from latest ruby 1.8.3 fixes this > behaviour. Your patch works fine, but I don't want to add the `tag' argument to send_*. How about this patch? Index: lib/net/imap.rb =================================================================== RCS file: /var/cvs/src/ruby/lib/net/imap.rb,v retrieving revision 1.39.2.11 diff -u -r1.39.2.11 imap.rb --- lib/net/imap.rb 22 Feb 2005 16:58:33 -0000 1.39.2.11 +++ lib/net/imap.rb 25 Sep 2005 01:27:45 -0000 @@ -902,8 +902,8 @@ @responses = Hash.new([].freeze) @tagged_responses = {} @response_handlers = [] - @tagged_response_arrival = new_cond - @continuation_request_arrival = new_cond + @response_arrival = new_cond + @continuation_request = nil @logout_command_tag = nil @debug_output_bol = true @@ -934,7 +934,7 @@ case resp when TaggedResponse @tagged_responses[resp.tag] = resp - @tagged_response_arrival.broadcast + @response_arrival.broadcast if resp.tag == @logout_command_tag return end @@ -949,7 +949,8 @@ raise ByeResponseError, resp.raw_data end when ContinuationRequest - @continuation_request_arrival.signal + @continuation_request = resp + @response_arrival.broadcast end @response_handlers.each do |handler| handler.call(resp) @@ -961,10 +962,14 @@ end end - def get_tagged_response(tag, cmd) + def get_tagged_response(tag) until @tagged_responses.key?(tag) - @tagged_response_arrival.wait + @response_arrival.wait end + return pick_up_tagged_response(tag) + end + + def pick_up_tagged_response(tag) resp = @tagged_responses.delete(tag) case resp.name when /\A(?:NO)\z/ni @@ -1005,7 +1010,7 @@ def send_command(cmd, *args, &block) synchronize do - tag = generate_tag + tag = Thread.current[:net_imap_tag] = generate_tag put_string(tag + " " + cmd) args.each do |i| put_string(" ") @@ -1019,7 +1024,7 @@ add_response_handler(block) end begin - return get_tagged_response(tag, cmd) + return get_tagged_response(tag) ensure if block remove_response_handler(block) @@ -1088,7 +1093,15 @@ def send_literal(str) put_string("{" + str.length.to_s + "}" + CRLF) - @continuation_request_arrival.wait + while @continuation_request.nil? && + !@tagged_responses.key?(Thread.current[:net_imap_tag]) + @response_arrival.wait + end + if @continuation_request.nil? + pick_up_tagged_response(Thread.current[:net_imap_tag]) + raise ResponseError.new("expected continuation request") + end + @continuation_request = nil put_string(str) end Shugo