Commit 24cec9fe authored by Gregory P. Smith's avatar Gregory P. Smith

Merged revisions 78527,78550 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r78527 | gregory.p.smith | 2010-02-28 17:22:39 -0800 (Sun, 28 Feb 2010) | 4 lines

  Issue #7242: On Solaris 9 and earlier calling os.fork() from within a
  thread could raise an incorrect RuntimeError about not holding the import
  lock.  The import lock is now reinitialized after fork.
........
  r78550 | gregory.p.smith | 2010-02-28 22:01:02 -0800 (Sun, 28 Feb 2010) | 2 lines

  Fix test to be skipped on windows.
........
parent c78d79ce
...@@ -4,6 +4,7 @@ import random ...@@ -4,6 +4,7 @@ import random
from test import support from test import support
import _thread as thread import _thread as thread
import time import time
import sys
import weakref import weakref
from test import lock_tests from test import lock_tests
...@@ -193,8 +194,47 @@ class LockTests(lock_tests.LockTests): ...@@ -193,8 +194,47 @@ class LockTests(lock_tests.LockTests):
locktype = thread.allocate_lock locktype = thread.allocate_lock
class TestForkInThread(unittest.TestCase):
def setUp(self):
self.read_fd, self.write_fd = os.pipe()
@unittest.skipIf(sys.platform.startswith('win'),
"This test is only appropriate for POSIX-like systems.")
def test_forkinthread(self):
def thread1():
try:
pid = os.fork() # fork in a thread
except RuntimeError:
os._exit(1) # exit the child
if pid == 0: # child
try:
os.close(self.read_fd)
os.write(self.write_fd, b"OK")
finally:
os._exit(0)
else: # parent
os.close(self.write_fd)
thread.start_new_thread(thread1, ())
self.assertEqual(os.read(self.read_fd, 2), b"OK",
"Unable to fork() in thread")
def tearDown(self):
try:
os.close(self.read_fd)
except OSError:
pass
try:
os.close(self.write_fd)
except OSError:
pass
def test_main(): def test_main():
support.run_unittest(ThreadRunningTests, BarrierTest, LockTests) support.run_unittest(ThreadRunningTests, BarrierTest, LockTests,
TestForkInThread)
if __name__ == "__main__": if __name__ == "__main__":
test_main() test_main()
...@@ -751,6 +751,10 @@ Extension Modules ...@@ -751,6 +751,10 @@ Extension Modules
- Expat: Fix DoS via XML document with malformed UTF-8 sequences - Expat: Fix DoS via XML document with malformed UTF-8 sequences
(CVE_2009_3560). (CVE_2009_3560).
- Issue #7242: On Solaris 9 and earlier calling os.fork() from within a
thread could raise an incorrect RuntimeError about not holding the import
lock. The import lock is now reinitialized after fork.
- Issue #7999: os.setreuid() and os.setregid() would refuse to accept a -1 - Issue #7999: os.setreuid() and os.setregid() would refuse to accept a -1
parameter on some platforms such as OS X. parameter on some platforms such as OS X.
......
...@@ -3723,14 +3723,18 @@ static PyObject * ...@@ -3723,14 +3723,18 @@ static PyObject *
posix_fork1(PyObject *self, PyObject *noargs) posix_fork1(PyObject *self, PyObject *noargs)
{ {
pid_t pid; pid_t pid;
int result; int result = 0;
_PyImport_AcquireLock(); _PyImport_AcquireLock();
pid = fork1(); pid = fork1();
result = _PyImport_ReleaseLock(); if (pid == 0) {
/* child: this clobbers and resets the import lock. */
PyOS_AfterFork();
} else {
/* parent: release the import lock. */
result = _PyImport_ReleaseLock();
}
if (pid == -1) if (pid == -1)
return posix_error(); return posix_error();
if (pid == 0)
PyOS_AfterFork();
if (result < 0) { if (result < 0) {
/* Don't clobber the OSError if the fork failed. */ /* Don't clobber the OSError if the fork failed. */
PyErr_SetString(PyExc_RuntimeError, PyErr_SetString(PyExc_RuntimeError,
...@@ -3752,14 +3756,18 @@ static PyObject * ...@@ -3752,14 +3756,18 @@ static PyObject *
posix_fork(PyObject *self, PyObject *noargs) posix_fork(PyObject *self, PyObject *noargs)
{ {
pid_t pid; pid_t pid;
int result; int result = 0;
_PyImport_AcquireLock(); _PyImport_AcquireLock();
pid = fork(); pid = fork();
result = _PyImport_ReleaseLock(); if (pid == 0) {
/* child: this clobbers and resets the import lock. */
PyOS_AfterFork();
} else {
/* parent: release the import lock. */
result = _PyImport_ReleaseLock();
}
if (pid == -1) if (pid == -1)
return posix_error(); return posix_error();
if (pid == 0)
PyOS_AfterFork();
if (result < 0) { if (result < 0) {
/* Don't clobber the OSError if the fork failed. */ /* Don't clobber the OSError if the fork failed. */
PyErr_SetString(PyExc_RuntimeError, PyErr_SetString(PyExc_RuntimeError,
...@@ -3877,11 +3885,12 @@ posix_forkpty(PyObject *self, PyObject *noargs) ...@@ -3877,11 +3885,12 @@ posix_forkpty(PyObject *self, PyObject *noargs)
_PyImport_AcquireLock(); _PyImport_AcquireLock();
pid = forkpty(&master_fd, NULL, NULL, NULL); pid = forkpty(&master_fd, NULL, NULL, NULL);
if (pid == 0)
PyOS_AfterFork();
result = _PyImport_ReleaseLock(); result = _PyImport_ReleaseLock();
if (pid == -1) if (pid == -1)
return posix_error(); return posix_error();
if (pid == 0)
PyOS_AfterFork();
if (result < 0) { if (result < 0) {
/* Don't clobber the OSError if the fork failed. */ /* Don't clobber the OSError if the fork failed. */
PyErr_SetString(PyExc_RuntimeError, PyErr_SetString(PyExc_RuntimeError,
......
...@@ -295,14 +295,18 @@ _PyImport_ReleaseLock(void) ...@@ -295,14 +295,18 @@ _PyImport_ReleaseLock(void)
return 1; return 1;
} }
/* This function used to be called from PyOS_AfterFork to ensure that newly /* This function is called from PyOS_AfterFork to ensure that newly
created child processes do not share locks with the parent, but for some created child processes do not share locks with the parent.
reason only on AIX systems. Instead of re-initializing the lock, we now We now acquire the import lock around fork() calls but on some platforms
acquire the import lock around fork() calls. */ (Solaris 9 and earlier? see isue7242) that still left us with problems. */
void void
_PyImport_ReInitLock(void) _PyImport_ReInitLock(void)
{ {
if (import_lock != NULL)
import_lock = PyThread_allocate_lock();
import_lock_thread = -1;
import_lock_level = 0;
} }
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment