@@ -182,10 +182,21 @@ def __init__(self, stream, address, request_callback, no_keep_alive=False,
182
182
self .protocol = protocol
183
183
self ._request = None
184
184
self ._request_finished = False
185
+ self ._write_callback = None
186
+ self ._close_callback = None
185
187
# Save stack context here, outside of any request. This keeps
186
188
# contexts from one request from leaking into the next.
187
189
self ._header_callback = stack_context .wrap (self ._on_headers )
188
190
self .stream .read_until (b"\r \n \r \n " , self ._header_callback )
191
+
192
+ def _clear_callbacks (self ):
193
+ """Clears the per-request callbacks.
194
+
195
+ This is run in between requests to allow the previous handler
196
+ to be garbage collected (and prevent spurious close callbacks),
197
+ and when the connection is closed (to break up cycles and
198
+ facilitate garbage collection in cpython).
199
+ """
189
200
self ._write_callback = None
190
201
self ._close_callback = None
191
202
@@ -205,13 +216,15 @@ def _on_connection_close(self):
205
216
self ._close_callback = None
206
217
callback ()
207
218
# Delete any unfinished callbacks to break up reference cycles.
208
- self ._write_callback = None
219
+ self ._header_callback = None
220
+ self ._clear_callbacks ()
209
221
210
222
def close (self ):
211
223
self .stream .close ()
212
224
# Remove this reference to self, which would otherwise cause a
213
225
# cycle and delay garbage collection of this connection.
214
226
self ._header_callback = None
227
+ self ._clear_callbacks ()
215
228
216
229
def write (self , chunk , callback = None ):
217
230
"""Writes a chunk of output to the stream."""
@@ -258,6 +271,7 @@ def _finish_request(self):
258
271
disconnect = True
259
272
self ._request = None
260
273
self ._request_finished = False
274
+ self ._clear_callbacks ()
261
275
if disconnect :
262
276
self .close ()
263
277
return
0 commit comments