Просмотр исходного кода

fixed DelayDelete-related crashes, fixed Toontown crashes on game exit

Darren Ranalli 17 лет назад
Родитель
Сommit
a232e570d8
2 измененных файлов с 35 добавлено и 14 удалено
  1. 9 0
      direct/src/distributed/DelayDelete.py
  2. 26 14
      direct/src/distributed/DistributedObject.py

+ 9 - 0
direct/src/distributed/DelayDelete.py

@@ -27,11 +27,20 @@ class DelayDelete:
 
 
     def __init__(self, distObj, name):
     def __init__(self, distObj, name):
         self._distObj = distObj
         self._distObj = distObj
+        self._name = name
         self._token = self._distObj.acquireDelayDelete(name)
         self._token = self._distObj.acquireDelayDelete(name)
 
 
+    def getObject(self):
+        return self._distObj
+
+    def getName(self):
+        return self._name
+
     def destroy(self):
     def destroy(self):
         token = self._token
         token = self._token
         # do this first to catch cases where releaseDelayDelete causes
         # do this first to catch cases where releaseDelayDelete causes
         # this method to be called again
         # this method to be called again
         del self._token
         del self._token
         self._distObj.releaseDelayDelete(token)
         self._distObj.releaseDelayDelete(token)
+        del self._distObj
+        del self._name

+ 26 - 14
direct/src/distributed/DistributedObject.py

@@ -192,14 +192,15 @@ class DistributedObject(DistributedObjectBase):
 
 
     def deleteOrDelay(self):
     def deleteOrDelay(self):
         if len(self._token2delayDeleteName) > 0:
         if len(self._token2delayDeleteName) > 0:
-            self.deleteImminent = 1
-            # Object is delayDeleted. Clean up distributedObject state,
-            # remove from repository tables, so that we won't crash if
-            # another instance of the same object gets generated while
-            # this instance is still delayDeleted.
-            messenger.send(self.getDisableEvent())
-            self.activeState = ESDisabled
-            self._deactivate()
+            if not self.deleteImminent:
+                self.deleteImminent = 1
+                # Object is delayDeleted. Clean up DistributedObject state,
+                # remove from repository tables, so that we won't crash if
+                # another instance of the same object gets generated while
+                # this instance is still delayDeleted.
+                messenger.send(self.getDelayDeleteEvent())
+                self.delayDelete()
+                self._deactivateDO()
         else:
         else:
             self.disableAnnounceAndDelete()
             self.disableAnnounceAndDelete()
 
 
@@ -240,13 +241,12 @@ class DistributedObject(DistributedObjectBase):
             assert self.notify.debug(
             assert self.notify.debug(
                 "delayDelete count for doId %s now 0" % (self.doId))
                 "delayDelete count for doId %s now 0" % (self.doId))
             self.cr._removeDelayDeletedDO(self)
             self.cr._removeDelayDeletedDO(self)
+            # do we have a pending delete?
             if self.deleteImminent:
             if self.deleteImminent:
                 assert self.notify.debug(
                 assert self.notify.debug(
                     "delayDelete count for doId %s -- deleteImminent" %
                     "delayDelete count for doId %s -- deleteImminent" %
                     (self.doId))
                     (self.doId))
-                self.disable()
-                self.delete()
-                self._destroyDO()
+                self.disableAnnounceAndDelete()
 
 
     def getDelayDeleteNames(self):
     def getDelayDeleteNames(self):
         return self._token2delayDeleteName.values()
         return self._token2delayDeleteName.values()
@@ -256,6 +256,9 @@ class DistributedObject(DistributedObjectBase):
         self.delete()
         self.delete()
         self._destroyDO()
         self._destroyDO()
 
 
+    def getDelayDeleteEvent(self):
+        return self.uniqueName("delayDelete")
+
     def getDisableEvent(self):
     def getDisableEvent(self):
         return self.uniqueName("disable")
         return self.uniqueName("disable")
 
 
@@ -274,7 +277,10 @@ class DistributedObject(DistributedObjectBase):
             messenger.send(self.getDisableEvent())
             messenger.send(self.getDisableEvent())
             self.disable()
             self.disable()
             self.activeState = ESDisabled
             self.activeState = ESDisabled
-            self._deactivate()
+            if not self.deleteImminent:
+                # if deleteImminent was set, it was DelayDeleted and _deactivateDO was
+                # already called
+                self._deactivateDO()
 
 
     def announceGenerate(self):
     def announceGenerate(self):
         """
         """
@@ -284,12 +290,12 @@ class DistributedObject(DistributedObjectBase):
         assert self.notify.debug('announceGenerate(): %s' % (self.doId))
         assert self.notify.debug('announceGenerate(): %s' % (self.doId))
 
 
 
 
-    def _deactivate(self):
+    def _deactivateDO(self):
         # after this is called, the object is no longer an active DistributedObject
         # after this is called, the object is no longer an active DistributedObject
         # and it may be placed in the cache
         # and it may be placed in the cache
         if not self.cr:
         if not self.cr:
             # we are going to crash, output the destroyDo stacktrace
             # we are going to crash, output the destroyDo stacktrace
-            self.notify.warning('self.cr is none in _deactivate %d' % self.doId)
+            self.notify.warning('self.cr is none in _deactivateDO %d' % self.doId)
             if hasattr(self, 'destroyDoStackTrace'):
             if hasattr(self, 'destroyDoStackTrace'):
                 print self.destroyDoStackTrace
                 print self.destroyDoStackTrace
         self.__callbacks = {}
         self.__callbacks = {}
@@ -311,6 +317,12 @@ class DistributedObject(DistributedObjectBase):
         self.cr = None
         self.cr = None
         self.dclass = None
         self.dclass = None
 
 
+    def delayDelete(self):
+        """
+        Inheritors should redefine this to take appropriate action on delayDelete
+        """
+        pass
+
     def disable(self):
     def disable(self):
         """
         """
         Inheritors should redefine this to take appropriate action on disable
         Inheritors should redefine this to take appropriate action on disable