diff --git a/direct/src/showbase/Messenger.py b/direct/src/showbase/Messenger.py index f62dfa021d..d6651bc2ff 100644 --- a/direct/src/showbase/Messenger.py +++ b/direct/src/showbase/Messenger.py @@ -5,9 +5,72 @@ __all__ = ['Messenger'] from PythonUtil import * from direct.directnotify import DirectNotifyGlobal -from direct.stdpy.threading import Lock import types +# This one line will replace the cheesy hack below, when we remove the +# hack. +#from direct.stdpy.threading import Lock + +class Lock: + """ This is a cheesy delayed implementation of Lock, designed to + support the Toontown ActiveX launch, which must import Messenger + before it has downloaded the rest of Panda. This is a TEMPORARY + HACK, to be removed when the ActiveX launch is retired. """ + + notify = DirectNotifyGlobal.directNotify.newCategory("Messenger.Lock") + + def __init__(self): + self.locked = 0 + + def acquire(self): + # Before we download Panda, we can't use any threading + # interfaces. So don't, until we observe that we have some + # actual contention on the lock. + + if self.locked: + # We have contention. + return self.__getLock() + + # This relies on the fact that any individual Python statement + # is atomic. + self.locked += 1 + if self.locked > 1: + # Whoops, we have contention. + self.locked -= 1 + return self.__getLock() + + def release(self): + if self.locked: + # Still using the old, cheesy lock. + self.locked -= 1 + return + + # The new lock must have been put in place. + self.release = self.lock.release + return self.lock.release() + + def __getLock(self): + # Now that we've started Panda, it's safe to import the Mutex + # class, which becomes our actual lock. + # From now on, this lock will be used. + + self.notify.info("Acquiring Panda lock for the first time.") + + from pandac.PandaModules import Thread, Mutex + self.__dict__.setdefault('lock', Mutex('Messenger')) + self.lock.acquire() + + self.acquire = self.lock.acquire + + # Wait for the cheesy lock to be released before we return. + self.notify.info("Waiting for cheesy lock to be released.") + while self.locked: + Thread.forceYield() + self.notify.info("Got cheesy lock.") + + # We return with the lock acquired. + + class Messenger: notify = DirectNotifyGlobal.directNotify.newCategory("Messenger")