Преглед изворни кода

remove DO from location tables etc. before delayDeleting, fixes 'duplicate generate' client crashes

Darren Ranalli пре 18 година
родитељ
комит
9a0cfd2725
1 измењених фајлова са 28 додато и 10 уклоњено
  1. 28 10
      direct/src/distributed/DistributedObject.py

+ 28 - 10
direct/src/distributed/DistributedObject.py

@@ -145,6 +145,13 @@ class DistributedObject(DistributedObjectBase):
     def deleteOrDelay(self):
         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()
         else:
             self.disableAnnounceAndDelete()
 
@@ -178,7 +185,9 @@ class DistributedObject(DistributedObjectBase):
                 assert self.notify.debug(
                     "delayDelete count for doId %s -- deleteImminent" %
                     (self.doId))
-                self.disableAnnounceAndDelete()
+                self.disable()
+                self.delete()
+                self._destroyDO()
 
     def getDelayDeleteNames(self):
         return self._token2delayDeleteName.values()
@@ -186,6 +195,7 @@ class DistributedObject(DistributedObjectBase):
     def disableAnnounceAndDelete(self):
         self.disableAndAnnounce()
         self.delete()
+        self._destroyDO()
 
     def getDisableEvent(self):
         return self.uniqueName("disable")
@@ -204,6 +214,8 @@ class DistributedObject(DistributedObjectBase):
             self.activeState = ESDisabling
             messenger.send(self.getDisableEvent())
             self.disable()
+            self.activeState = ESDisabled
+            self._deactivate()
 
     def announceGenerate(self):
         """
@@ -213,18 +225,26 @@ class DistributedObject(DistributedObjectBase):
         assert self.notify.debug('announceGenerate(): %s' % (self.doId))
 
 
+    def _deactivate(self):
+        # after this is called, the object is no longer an active DistributedObject
+        # and it may be placed in the cache
+        self.__callbacks = {}
+        self.cr.closeAutoInterests(self)
+        self.setLocation(0,0)
+        self.cr.deleteObjectLocation(self, self.parentId, self.zoneId)
+
+    def _destroyDO(self):
+        # after this is called, the object is no longer a DistributedObject
+        # but may still be used as a DelayDeleted object
+        self.cr = None
+        self.dclass = None
+
     def disable(self):
         """
         Inheritors should redefine this to take appropriate action on disable
         """
         assert self.notify.debug('disable(): %s' % (self.doId))
-        if self.activeState != ESDisabled:
-            self.activeState = ESDisabled
-            self.__callbacks = {}
-            self.cr.closeAutoInterests(self)
-            self.setLocation(0,0)
-            self.cr.deleteObjectLocation(self, self.parentId, self.zoneId)
-            # TODO: disable my children
+        pass
 
     def isDisabled(self):
         """
@@ -250,8 +270,6 @@ class DistributedObject(DistributedObjectBase):
             self.DistributedObject_deleted
         except:
             self.DistributedObject_deleted = 1
-            self.cr = None
-            self.dclass = None
 
     def generate(self):
         """