Condition.wait(0.5) doesn't respect it's timeout

stephane.bisinger at gmail.com stephane.bisinger at gmail.com
Sat Apr 18 14:38:16 CEST 2009


On Apr 18, 10:24 am, Piet van Oostrum <p... at cs.uu.nl> wrote:
>
> I haven't run it (too much hassle to setup) but I noticed one strange
> thing in your code:
>
> ,----
> | def groupUpdated(self, gView):
> |         # Acquire the lock to do modifications
> |         self._mod_lock.acquire()
> |  
> |         if not self._groups.has_key(gView.uid):
> |             return
> `----
>
> In case the return is taken, the lock will not be released thereby
> blocking the rest. It could be that the timeout is taken, but before the
> wait can continue it has to acquire the lock again.

That is absolutely correct, but I guess with an RLock there shouldn't
be a deadlock... Anyway I'm fixing that!

>
> It is best to put all your code after the acquire in a try: finally:
> like
>
> ,----
> | self._mod_lock.acquire()
> | try:
> |         do something
> | finally:
> |         self._mod_lock.release()
> `----
>
> or even better use the with statement:
>
> ,----
> | with self._mod_lock:
> |      do something
> `----
> It will do the releasing automatically

Thanks for the advice!

> And then something else:
> ,----
> | def __thread_run(self):
> |        while True:
> |            import sys
> |            print >> sys.stderr, "at loop start"
> |            self._mod_lock.acquire()
> |            t = time.time()
> |            # We don't want to work before at least half a second has passed
> |            while time.time() - t < 0.5 or not self._modified:
> |                print >> sys.stderr, "Going to sleep\n"
> |                self._mod_lock.wait(timeout=1)
> |                print >> sys.stderr, "Ok time to see if we must repaint"
> |            self.__repaint()
> |            t = time.time()
> |            self._mod_lock.release()
> |            print >> sys.stderr, "at loop end"
> |            self._mod_lock.acquire()
> `----
>
> Your loop ends with self._mod_lock.acquire() but in the next round there
> is another self._mod_lock.acquire() at the beginning of the loop. So the
> acquire at the end isn't necessary.

I have no idea how that came to be, probably pasted one line where I
shouldn't have, it's gone ;)

Anyway I cleaned up that mess and here is the resulting code, with the
same issues:
http://github.com/Kjir/amsn2/commit/bda6829d0c7d50a1cbf1188cdfa3789c4b7967c5
http://github.com/Kjir/amsn2/blob/bda6829d0c7d50a1cbf1188cdfa3789c4b7967c5/amsn2/gui/front_ends/curses/contact_list.py

I'll also file a bug report because I am more and more convinced this
is a bug, if anything else at least in the documentation...



More information about the Python-list mailing list