Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Don't attempt to wait() on event if already finished

Fixes a regression added in e757fe1, which is a race condition on a call
like:

    some_fast_threaded_task().wait()

If the thread finishes before wait() is called then the caller would block
waiting on an event that is never set.
  • Loading branch information...
commit acf5a637f681d5af281450c0bf0e6da9a34d6524 1 parent 4dd32e2
Jason Tackaberry jtackaberry authored

Showing 1 changed file with 6 additions and 4 deletions. Show diff stats Hide diff stats

  1. +6 4 src/async.py
10 src/async.py
@@ -416,15 +416,19 @@ def _finished_event_poke(self, **kwargs):
416 416 Because we're doing a test-and-create we need a mutex, and because this
417 417 is not a common operation, we avoid the (roughly 7%) overhead of
418 418 a per-instance lock. It means that all instances will synchronize on
419   - this mutex but because it's so rarely used I doubt there will be any
420   - contention on the lock.
  419 + this mutex but because it's so rarely accessed from multiple threads I
  420 + doubt there will be any contention on the lock.
421 421 """
422 422 if kwargs.get('set'):
423 423 with self._finished_event_lock:
  424 + self._finished = True
424 425 if self._finished_event:
425 426 self._finished_event.set()
426 427 elif 'wait' in kwargs:
427 428 with self._finished_event_lock:
  429 + if self._finished:
  430 + # Nothing to wait on, we're already done.
  431 + return
428 432 if not self._finished_event:
429 433 self._finished_event = threading.Event()
430 434 self._finished_event.wait(kwargs['wait'])
@@ -455,7 +459,6 @@ def finish(self, result):
455 459 return self
456 460
457 461 # store result
458   - self._finished = True
459 462 self._result = result
460 463 self._exception = None
461 464 # Wake any threads waiting on us
@@ -503,7 +506,6 @@ def throw(self, type=None, value=None, tb=None, aborted=False):
503 506 # custom traceback object in C code that preserves the parts of the
504 507 # stack frames needed for printing tracebacks, but discarding objects
505 508 # that would create circular references. This might be a TODO.
506   - self._finished = True
507 509 if type is None:
508 510 type, value, tb = sys.exc_info()
509 511 if value is None:

0 comments on commit acf5a63

Please sign in to comment.
Something went wrong with that request. Please try again.