bpo-36368: Ignore SIGINT in SharedMemoryManager servers. (GH-12483)
authorPierre Glaser <pierreglaser@msn.com>
Fri, 10 May 2019 18:42:35 +0000 (20:42 +0200)
committerAntoine Pitrou <antoine@python.org>
Fri, 10 May 2019 18:42:35 +0000 (20:42 +0200)
Fix a bug crashing SharedMemoryManager instances in interactive sessions after
a Ctrl-C (KeyboardInterrupt) was sent.

Lib/multiprocessing/managers.py
Lib/test/_test_multiprocessing.py
Misc/NEWS.d/next/Library/2019-03-21-16-00-00.bpo-36368.zsRT1.rst [new file with mode: 0644]

index 22abd47fb1f23f1fd6594bffc021434feee5d44d..2bad636855fe6279bc6880a99c7f77bc60eeafff 100644 (file)
@@ -17,6 +17,7 @@ __all__ = [ 'BaseManager', 'SyncManager', 'BaseProxy', 'Token',
 
 import sys
 import threading
+import signal
 import array
 import queue
 import time
@@ -596,6 +597,9 @@ class BaseManager(object):
         '''
         Create a server, report its address and run it
         '''
+        # bpo-36368: protect server process from KeyboardInterrupt signals
+        signal.signal(signal.SIGINT, signal.SIG_IGN)
+
         if initializer is not None:
             initializer(*initargs)
 
index 836fde88cd266db83db4c0b3594056b6ecfef2e9..d97e4232f7ac2ed4c53fbf53fb833832e9a86f42 100644 (file)
@@ -3734,6 +3734,30 @@ class _TestSharedMemory(BaseTestCase):
 
         sms.close()
 
+    @unittest.skipIf(os.name != "posix", "not feasible in non-posix platforms")
+    def test_shared_memory_SharedMemoryServer_ignores_sigint(self):
+        # bpo-36368: protect SharedMemoryManager server process from
+        # KeyboardInterrupt signals.
+        smm = multiprocessing.managers.SharedMemoryManager()
+        smm.start()
+
+        # make sure the manager works properly at the beginning
+        sl = smm.ShareableList(range(10))
+
+        # the manager's server should ignore KeyboardInterrupt signals, and
+        # maintain its connection with the current process, and success when
+        # asked to deliver memory segments.
+        os.kill(smm._process.pid, signal.SIGINT)
+
+        sl2 = smm.ShareableList(range(10))
+
+        # test that the custom signal handler registered in the Manager does
+        # not affect signal handling in the parent process.
+        with self.assertRaises(KeyboardInterrupt):
+            os.kill(os.getpid(), signal.SIGINT)
+
+        smm.shutdown()
+
     def test_shared_memory_SharedMemoryManager_basics(self):
         smm1 = multiprocessing.managers.SharedMemoryManager()
         with self.assertRaises(ValueError):
diff --git a/Misc/NEWS.d/next/Library/2019-03-21-16-00-00.bpo-36368.zsRT1.rst b/Misc/NEWS.d/next/Library/2019-03-21-16-00-00.bpo-36368.zsRT1.rst
new file mode 100644 (file)
index 0000000..d842682
--- /dev/null
@@ -0,0 +1,2 @@
+Fix a bug crashing SharedMemoryManager instances in interactive sessions after
+a ctrl-c (KeyboardInterrupt) was sent