Merged revisions 87710 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k

........
  r87710 | gregory.p.smith | 2011-01-03 13:06:12 -0800 (Mon, 03 Jan 2011) | 4 lines

  issue6643 - Two locks held within the threading module on each thread instance
  needed to be reinitialized after fork().  Adds tests to confirm that they are
  and that a potential deadlock and crasher bug are fixed (platform dependant).
........

This required a bit more fiddling for 2.x as __block and __started are __
private as well as the __started Event's __cond.  A new "private"
_reset_internal_locks() method is added to Thread and _Event objects to
address this.
diff --git a/Lib/threading.py b/Lib/threading.py
index 5ac45e1..b05597d 100644
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -373,6 +373,10 @@
         self.__cond = Condition(Lock())
         self.__flag = False
 
+    def _reset_internal_locks(self):
+        # private!  called by Thread._reset_internal_locks by _after_fork()
+        self.__cond.__init__()
+
     def isSet(self):
         return self.__flag
 
@@ -449,6 +453,17 @@
         # sys.exc_info since it can be changed between instances
         self.__stderr = _sys.stderr
 
+    def _reset_internal_locks(self):
+        # private!  Called by _after_fork() to reset our internal locks as
+        # they may be in an invalid state leading to a deadlock or crash.
+        self.__block.__init__()
+        self.__started._reset_internal_locks()
+
+    @property
+    def _block(self):
+        # used by a unittest
+        return self.__block
+
     def _set_daemon(self):
         # Overridden in _MainThread and _DummyThread
         return current_thread().daemon
@@ -867,6 +882,9 @@
                 # its new value since it can have changed.
                 ident = _get_ident()
                 thread._Thread__ident = ident
+                # Any condition variables hanging off of the active thread may
+                # be in an invalid state, so we reinitialize them.
+                thread._reset_internal_locks()
                 new_active[ident] = thread
             else:
                 # All the others are already stopped.