Skip to content

Commit 4d13606

Browse files
committed
🧵 #Close socket before waiting for lock
Net::IMAP#disconnect will still attempt to enter the logout state first, but it won't wait for the lock until after the socket has been shutdown.
1 parent f31b706 commit 4d13606

1 file changed

Lines changed: 15 additions & 1 deletion

File tree

lib/net/imap.rb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1133,7 +1133,7 @@ def tls_verified?; @tls_verified end
11331133
#
11341134
# Related: #logout, #logout!
11351135
def disconnect
1136-
state_logout! unless connection_state.to_sym == :logout
1136+
in_logout_state = try_state_logout?
11371137
return if disconnected?
11381138
begin
11391139
begin
@@ -1153,6 +1153,10 @@ def disconnect
11531153
@sock.close
11541154
end
11551155
raise e if e
1156+
ensure
1157+
# Try again after shutting down the receiver thread. With no reciever
1158+
# left to wait for, any remaining locks should be _very_ brief.
1159+
state_logout! unless in_logout_state
11561160
end
11571161

11581162
# Returns true if disconnected from the server.
@@ -3817,6 +3821,16 @@ def state_logout!
38173821
end
38183822
end
38193823

3824+
# don't wait to aqcuire the lock
3825+
def try_state_logout?
3826+
return true if connection_state in [:logout, *]
3827+
return false unless acquired_lock = mon_try_enter
3828+
state_logout!
3829+
true
3830+
ensure
3831+
mon_exit if acquired_lock
3832+
end
3833+
38203834
def sasl_adapter
38213835
SASLAdapter.new(self, &method(:send_command_with_continuations))
38223836
end

0 commit comments

Comments
 (0)