threading.Condition.wait(timeout) ignores threading.Condition.notify()
Question: I have an application that uses 2 threads. I want to be able to shut down both
threads by waiting for a condition variable `exitCondition`. I am using python
3.3 which unlike python 2.7 makes `threading.Condition.wait()` return `True`
when the condition was notified and `False` for when a timeout occured.

    
    
    #!/usr/bin/python
    import threading
    from time import sleep
    
    exitCondition = threading.Condition()
    
    def inputActivity():
        while True:
            exitCondition.acquire()
            exitConditionReached = exitCondition.wait(.1) #<-critical
            print(exitConditionReached)
            exitCondition.release()
            if exitConditionReached: #exitCondition reached -> shutdown
                return
            else: #exitCondition not reached -> do work
                sleep(.1)
    
    inThread = threading.Thread(target = inputActivity)
    inThread.start()
    
    sleep(.2) #<-critical
    
    exitCondition.acquire()
    exitCondition.notify()
    print("exitCondition notified")
    exitCondition.release()
    
    inThread.join()
    

There are 2 lines with a `#<-critical` comment in line 10 and 21. If the
`sleep`s are "misaligned" (for example .25 and .1) the program will terminate.
If the `sleep`s are "aligned" (for example .2 and .1) the `inThread` will run
indefinitely printing `false` forever. It looks like a race condition to me,
apparently if `notify` is called at the same time as `wait` the notification
is not recognized. I was under the impression that the
`exitCondition.acquire()` and `exitCondition.release()` were supposed to
prevent that. The question is why the condition variable is not thread safe
and what I can do about it. Ideally I want to write `wait(0)` with the
guarantee that no notification will be swallowed.


Answer: If the call to `exitCondition.notify` occurs when the worker thread is doing
work (i.e., is in the `sleep(.1)` call (or anywhere else other than the
`.wait` call), then the behaviour you describe sounds like exactly what I'd
expect. The `wait` call returns `True` only if the notification happened
_during_ the `wait`.

It sounds to me as though this is a use-case for a `threading.Event` instead
of a `threading.Condition`: replace `threading.Condition` with
`threading.Event`, replace the `notify` call with a `set` call, and remove the
`acquire` and `release` calls altogether (in both threads).

That is, the code should look like this:

    
    
    #!/usr/bin/python
    import threading
    from time import sleep
    
    exitCondition = threading.Event()
    
    def inputActivity():
        while True:
            exitConditionReached = exitCondition.wait(.1) #<-critical
            print(exitConditionReached)
            if exitConditionReached: #exitCondition reached -> shutdown
                return
            else: #exitCondition not reached -> do work
                sleep(.1)
    
    inThread = threading.Thread(target = inputActivity)
    inThread.start()
    
    sleep(.2) #<-critical
    
    exitCondition.set()
    print("exitCondition set")
    
    inThread.join()
    

Once you've got that far, you don't need the first `.wait`: you can replace
that with a direct `is_set` call to see if the exit condition has been set
yet:

    
    
    #!/usr/bin/python
    import threading
    from time import sleep
    
    exitCondition = threading.Event()
    
    def inputActivity():
        while True:
            if exitCondition.is_set(): #exitCondition reached -> shutdown
                return
            else: #exitCondition not reached -> do work
                sleep(.1)
    
    inThread = threading.Thread(target = inputActivity)
    inThread.start()
    
    sleep(.2) #<-critical
    
    exitCondition.set()
    print("exitCondition set")
    
    inThread.join()
    

