Skip to content

Commit

Permalink
Delete HTTPConnection._close_callback in between requests.
Browse files Browse the repository at this point in the history
Previously the close callback would cause a reference to the previous
RequestHandler to be retained while waiting for the next request.
  • Loading branch information
bdarnell committed Mar 25, 2013
1 parent e00e4c6 commit 646f92f
Showing 1 changed file with 15 additions and 1 deletion.
16 changes: 15 additions & 1 deletion tornado/httpserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,21 @@ def __init__(self, stream, address, request_callback, no_keep_alive=False,
self.protocol = protocol
self._request = None
self._request_finished = False
self._write_callback = None
self._close_callback = None
# Save stack context here, outside of any request. This keeps
# contexts from one request from leaking into the next.
self._header_callback = stack_context.wrap(self._on_headers)
self.stream.read_until(b"\r\n\r\n", self._header_callback)

def _clear_callbacks(self):
"""Clears the per-request callbacks.
This is run in between requests to allow the previous handler
to be garbage collected (and prevent spurious close callbacks),
and when the connection is closed (to break up cycles and
facilitate garbage collection in cpython).
"""
self._write_callback = None
self._close_callback = None

Expand All @@ -205,13 +216,15 @@ def _on_connection_close(self):
self._close_callback = None
callback()
# Delete any unfinished callbacks to break up reference cycles.
self._write_callback = None
self._header_callback = None
self._clear_callbacks()

def close(self):
self.stream.close()
# Remove this reference to self, which would otherwise cause a
# cycle and delay garbage collection of this connection.
self._header_callback = None
self._clear_callbacks()

def write(self, chunk, callback=None):
"""Writes a chunk of output to the stream."""
Expand Down Expand Up @@ -258,6 +271,7 @@ def _finish_request(self):
disconnect = True
self._request = None
self._request_finished = False
self._clear_callbacks()
if disconnect:
self.close()
return
Expand Down

0 comments on commit 646f92f

Please sign in to comment.