@@ -70,29 +70,21 @@ def __init__(
7070 self .server = server
7171 self .adj = adj
7272 self .outbufs = [OverflowableBuffer (adj .outbuf_overflow )]
73+ self .total_outbufs_len = 0
7374 self .creation_time = self .last_activity = time .time ()
7475
7576 # task_lock used to push/pop requests
7677 self .task_lock = threading .Lock ()
7778 # outbuf_lock used to access any outbuf
78- self .outbuf_lock = threading .Lock ()
79+ self .outbuf_lock = threading .RLock ()
7980
8081 wasyncore .dispatcher .__init__ (self , sock , map = map )
8182
8283 # Don't let wasyncore.dispatcher throttle self.addr on us.
8384 self .addr = addr
8485
8586 def any_outbuf_has_data (self ):
86- for outbuf in self .outbufs :
87- if bool (outbuf ):
88- return True
89- return False
90-
91- def total_outbufs_len (self ):
92- # genexpr == more funccalls
93- # use b.__len__ rather than len(b) FBO of not getting OverflowError
94- # on Python 2
95- return sum ([b .__len__ () for b in self .outbufs ])
87+ return self .total_outbufs_len > 0
9688
9789 def writable (self ):
9890 # if there's data in the out buffer or we've been instructed to close
@@ -124,7 +116,7 @@ def handle_write(self):
124116 # won't get done.
125117 flush = self ._flush_some_if_lockable
126118 self .force_flush = False
127- elif (self .total_outbufs_len () >= self .adj .send_bytes ):
119+ elif (self .total_outbufs_len >= self .adj .send_bytes ):
128120 # 1. There's a running task, so we need to try to lock
129121 # the outbuf before sending
130122 # 2. Only try to send if the data in the out buffer is larger
@@ -196,7 +188,9 @@ def received(self, data):
196188 if not self .sent_continue :
197189 # there's no current task, so we don't need to try to
198190 # lock the outbuf to append to it.
199- self .outbufs [- 1 ].append (b'HTTP/1.1 100 Continue\r \n \r \n ' )
191+ outbuf_payload = b'HTTP/1.1 100 Continue\r \n \r \n '
192+ self .outbufs [- 1 ].append (outbuf_payload )
193+ self .total_outbufs_len += len (outbuf_payload )
200194 self .sent_continue = True
201195 self ._flush_some ()
202196 request .completed = False
@@ -261,6 +255,7 @@ def _flush_some(self):
261255 outbuf .skip (num_sent , True )
262256 outbuflen -= num_sent
263257 sent += num_sent
258+ self .total_outbufs_len -= num_sent
264259 else :
265260 dobreak = True
266261 break
@@ -275,15 +270,15 @@ def _flush_some(self):
275270 return False
276271
277272 def handle_close (self ):
278- # avoid closing the outbufs while a task is potentially adding data
279- # to them in write_soon
273+ # NB: default to True for when asyncore calls this function directly
280274 with self .outbuf_lock :
281275 for outbuf in self .outbufs :
282276 try :
283277 outbuf .close ()
284278 except :
285279 self .logger .exception (
286280 'Unknown exception while trying to close outbuf' )
281+ self .total_outbufs_len = 0
287282 self .connected = False
288283 wasyncore .dispatcher .close (self )
289284
@@ -330,11 +325,13 @@ def write_soon(self, data):
330325 self .outbufs .append (nextbuf )
331326 else :
332327 self .outbufs [- 1 ].append (data )
328+ num_bytes = len (data )
329+ self .total_outbufs_len += num_bytes
333330 # XXX We might eventually need to pull the trigger here (to
334331 # instruct select to stop blocking), but it slows things down so
335332 # much that I'll hold off for now; "server push" on otherwise
336333 # unbusy systems may suffer.
337- return len ( data )
334+ return num_bytes
338335 return 0
339336
340337 def service (self ):
0 commit comments