Skip to content

Commit fab8f1a

Browse files
committed
fix a deadlock when the client disconnects while flushing data
1 parent 2493202 commit fab8f1a

File tree

1 file changed

+10
-6
lines changed

1 file changed

+10
-6
lines changed

waitress/channel.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ def handle_write(self):
151151
self.will_close = True
152152

153153
if self.will_close:
154-
self.handle_close()
154+
self.handle_close(lock=False)
155155

156156
def readable(self):
157157
# We might want to create a new task. We can only do this if:
@@ -168,7 +168,7 @@ def handle_read(self):
168168
except socket.error:
169169
if self.adj.log_socket_errors:
170170
self.logger.exception('Socket error')
171-
self.handle_close()
171+
self.handle_close(lock=True)
172172
return
173173
if data:
174174
self.last_activity = time.time()
@@ -274,17 +274,21 @@ def _flush_some(self):
274274

275275
return False
276276

277-
def handle_close(self):
278-
# avoid closing the outbufs while a task is potentially adding data
279-
# to them in write_soon
280-
with self.outbuf_lock:
277+
def handle_close(self, lock=True):
278+
# NB: default to True for when asyncore calls this function directly
279+
if lock:
280+
self.outbuf_lock.acquire()
281+
try:
281282
for outbuf in self.outbufs:
282283
try:
283284
outbuf.close()
284285
except:
285286
self.logger.exception(
286287
'Unknown exception while trying to close outbuf')
287288
self.connected = False
289+
finally:
290+
if lock:
291+
self.outbuf_lock.release()
288292
wasyncore.dispatcher.close(self)
289293

290294
def add_channel(self, map=None):

0 commit comments

Comments
 (0)