Browse Source

stdpy: fix issues with direct.stdpy.threading thread cleanup

Fixes: #164
rdb 8 years ago
parent
commit
1f017997f9
2 changed files with 17 additions and 9 deletions
  1. 5 4
      direct/src/stdpy/thread.py
  2. 12 5
      direct/src/stdpy/threading.py

+ 5 - 4
direct/src/stdpy/thread.py

@@ -227,10 +227,11 @@ def _remove_thread_id(threadId):
 
     _threadsLock.acquire()
     try:
-        thread, locals, wrapper = _threads[threadId]
-        assert thread.getPythonIndex() == threadId
-        del _threads[threadId]
-        thread.setPythonIndex(-1)
+        if threadId in _threads:
+            thread, locals, wrapper = _threads[threadId]
+            assert thread.getPythonIndex() == threadId
+            del _threads[threadId]
+            thread.setPythonIndex(-1)
 
     finally:
         _threadsLock.release()

+ 12 - 5
direct/src/stdpy/threading.py

@@ -108,6 +108,7 @@ class Thread(ThreadBase):
                 self.run()
             finally:
                 self.__thread = None
+                _thread._remove_thread_id(self.ident)
 
         self.__thread = core.PythonThread(call_run, None, name, name)
         threadId = _thread._add_thread(self.__thread, weakref.proxy(self))
@@ -120,15 +121,17 @@ class Thread(ThreadBase):
             _thread._remove_thread_id(self.ident)
 
     def is_alive(self):
-        return self.__thread is not None and self.__thread.is_started()
+        thread = self.__thread
+        return thread is not None and thread.is_started()
 
     isAlive = is_alive
 
     def start(self):
-        if self.__thread is None or self.__thread.is_started():
+        thread = self.__thread
+        if thread is None or thread.is_started():
             raise RuntimeError
 
-        if not self.__thread.start(core.TPNormal, True):
+        if not thread.start(core.TPNormal, True):
             raise RuntimeError
 
     def run(self):
@@ -142,8 +145,12 @@ class Thread(ThreadBase):
     def join(self, timeout = None):
         # We don't support a timed join here, sorry.
         assert timeout is None
-        self.__thread.join()
-        self.__thread = None
+        thread = self.__thread
+        if thread is not None:
+            thread.join()
+            # Clear the circular reference.
+            self.__thread = None
+            _thread._remove_thread_id(self.ident)
 
     def setName(self, name):
         self.__dict__['name'] = name