[pypy-commit] pypy default: reset mainthreadident after fork (thanks amaury)

bdkearns noreply at buildbot.pypy.org
Sat Feb 9 05:55:49 CET 2013


Author: Brian Kearns <bdkearns at gmail.com>
Branch: 
Changeset: r60999:3b06320cf630
Date: 2013-02-08 23:42 -0500
http://bitbucket.org/pypy/pypy/changeset/3b06320cf630/

Log:	reset mainthreadident after fork (thanks amaury)

diff --git a/pypy/module/thread/gil.py b/pypy/module/thread/gil.py
--- a/pypy/module/thread/gil.py
+++ b/pypy/module/thread/gil.py
@@ -49,6 +49,8 @@
         return result
 
     def reinit_threads(self, space):
+        "Called in the child process after a fork()"
+        OSThreadLocals.reinit_threads(self, space)
         if self.gil_ready:     # re-initialize the gil if needed
             self._initialize_gil(space)
 
diff --git a/pypy/module/thread/test/test_fork.py b/pypy/module/thread/test/test_fork.py
--- a/pypy/module/thread/test/test_fork.py
+++ b/pypy/module/thread/test/test_fork.py
@@ -57,3 +57,30 @@
                 self.timeout_killer(pid, 5)
                 exitcode = os.waitpid(pid, 0)[1]
                 assert exitcode == 0 # if 9, process was killed by timer!
+
+    def test_forked_is_main_thread(self):
+        "Checks that a forked interpreter is the main thread"
+        import os, thread, signal
+
+        if not hasattr(os, 'fork'):
+            skip("No fork on this platform")
+
+        def threadfunction():
+            pid = os.fork()
+            if pid == 0:
+                print 'in child'
+                # signal() only works from the 'main' thread
+                signal.signal(signal.SIGUSR1, signal.SIG_IGN)
+                os._exit(42)
+            else:
+                self.timeout_killer(pid, 5)
+                exitcode = os.waitpid(pid, 0)[1]
+                feedback.append(exitcode)
+
+        feedback = []
+        thread.start_new_thread(threadfunction, ())
+        self.waitfor(lambda: feedback)
+        # if 0, an (unraisable) exception was raised from the forked thread.
+        # if 9, process was killed by timer.
+        # if 42<<8, os._exit(42) was correctly reached.
+        assert feedback == [42<<8]
diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py
--- a/pypy/module/thread/threadlocals.py
+++ b/pypy/module/thread/threadlocals.py
@@ -57,3 +57,7 @@
             thread_is_stopping(self.getvalue())
         finally:
             self.setvalue(None)
+
+    def reinit_threads(self, space):
+        "Called in the child process after a fork()"
+        self._mainthreadident = thread.get_ident()


More information about the pypy-commit mailing list