issue #360: missing locks around shutdown and LRU management.

This commit is contained in:
David Wilson 2018-09-12 18:56:06 +01:00
parent 498db57ec8
commit 7a00e1cc87
1 changed files with 25 additions and 19 deletions

View File

@ -187,29 +187,24 @@ class ContextService(mitogen.service.Service):
self._lock.release() self._lock.release()
return count return count
def _shutdown(self, context, lru=None, new_context=None): def _shutdown_unlocked(self, context, lru=None, new_context=None):
""" """
Arrange for `context` to be shut down, and optionally add `new_context` Arrange for `context` to be shut down, and optionally add `new_context`
to the LRU list while holding the lock. to the LRU list while holding the lock.
""" """
LOG.info('%r._shutdown(): shutting down %r', self, context) LOG.info('%r._shutdown_unlocked(): shutting down %r', self, context)
context.shutdown() context.shutdown()
key = self._key_by_context[context] key = self._key_by_context[context]
del self._response_by_key[key]
del self._refs_by_context[context]
del self._key_by_context[context]
if lru and context in lru:
lru.remove(context)
if new_context:
lru.append(new_context)
self._lock.acquire() def _update_lru_unlocked(self, new_context, spec, via):
try:
del self._response_by_key[key]
del self._refs_by_context[context]
del self._key_by_context[context]
if lru and context in lru:
lru.remove(context)
if new_context:
lru.append(new_context)
finally:
self._lock.release()
def _update_lru(self, new_context, spec, via):
""" """
Update the LRU ("MRU"?) list associated with the connection described Update the LRU ("MRU"?) list associated with the connection described
by `kwargs`, destroying the most recently created context if the list by `kwargs`, destroying the most recently created context if the list
@ -228,16 +223,27 @@ class ContextService(mitogen.service.Service):
'but they are all marked as in-use.', via) 'but they are all marked as in-use.', via)
return return
self._shutdown(context, lru=lru, new_context=new_context) self._shutdown_unlocked(context, lru=lru, new_context=new_context)
def _update_lru(self, new_context, spec, via):
self._lock.acquire()
try:
self._update_lru_unlocked(new_context, spec, via)
finally:
self._lock.release()
@mitogen.service.expose(mitogen.service.AllowParents()) @mitogen.service.expose(mitogen.service.AllowParents())
def shutdown_all(self): def shutdown_all(self):
""" """
For testing use, arrange for all connections to be shut down. For testing use, arrange for all connections to be shut down.
""" """
for context in list(self._key_by_context): self._lock.acquire()
self._shutdown(context) try:
self._lru_by_via = {} for context in list(self._key_by_context):
self._shutdown_unlocked(context)
self._lru_by_via = {}
finally:
self._lock.release()
def _on_stream_disconnect(self, stream): def _on_stream_disconnect(self, stream):
""" """