[Python-checkins] [3.7] bpo-39850: Add support for abstract sockets in multiprocessing (GH-18866) (GH-18877)
Pablo Galindo
webhook-mailer at python.org
Mon Mar 9 10:47:56 EDT 2020
https://github.com/python/cpython/commit/2235e04170503673471d5ec2e7c693cdadcbdc65
commit: 2235e04170503673471d5ec2e7c693cdadcbdc65
branch: 3.7
author: Pablo Galindo <Pablogsal at gmail.com>
committer: GitHub <noreply at github.com>
date: 2020-03-09T14:47:50Z
summary:
[3.7] bpo-39850: Add support for abstract sockets in multiprocessing (GH-18866) (GH-18877)
(cherry picked from commit 6012f30beff7fa8396718dfb198ccafc333c565b)
files:
A Misc/NEWS.d/next/Library/2020-03-09-01-45-06.bpo-39850.eaJNIE.rst
M Lib/multiprocessing/connection.py
M Lib/multiprocessing/forkserver.py
M Lib/multiprocessing/util.py
M Lib/test/_test_multiprocessing.py
diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py
index 1f3ea504fff43..6b92cf8a128f6 100644
--- a/Lib/multiprocessing/connection.py
+++ b/Lib/multiprocessing/connection.py
@@ -102,7 +102,7 @@ def address_type(address):
return 'AF_INET'
elif type(address) is str and address.startswith('\\\\'):
return 'AF_PIPE'
- elif type(address) is str:
+ elif type(address) is str or util.is_abstract_socket_namespace(address):
return 'AF_UNIX'
else:
raise ValueError('address type of %r unrecognized' % address)
@@ -587,7 +587,8 @@ def __init__(self, address, family, backlog=1):
self._family = family
self._last_accepted = None
- if family == 'AF_UNIX':
+ if family == 'AF_UNIX' and not util.is_abstract_socket_namespace(address):
+ # Linux abstract socket namespaces do not need to be explicitly unlinked
self._unlink = util.Finalize(
self, os.unlink, args=(address,), exitpriority=0
)
diff --git a/Lib/multiprocessing/forkserver.py b/Lib/multiprocessing/forkserver.py
index 040b46e66a033..ffd1735848c45 100644
--- a/Lib/multiprocessing/forkserver.py
+++ b/Lib/multiprocessing/forkserver.py
@@ -116,7 +116,8 @@ def ensure_running(self):
with socket.socket(socket.AF_UNIX) as listener:
address = connection.arbitrary_address('AF_UNIX')
listener.bind(address)
- os.chmod(address, 0o600)
+ if not util.is_abstract_socket_namespace(address):
+ os.chmod(address, 0o600)
listener.listen()
# all client processes own the write end of the "alive" pipe;
diff --git a/Lib/multiprocessing/util.py b/Lib/multiprocessing/util.py
index 0f9eac7e9fb4d..f5331abe821fb 100644
--- a/Lib/multiprocessing/util.py
+++ b/Lib/multiprocessing/util.py
@@ -102,6 +102,29 @@ def log_to_stderr(level=None):
_log_to_stderr = True
return _logger
+
+# Abstract socket support
+
+def _platform_supports_abstract_sockets():
+ if sys.platform == "linux":
+ return True
+ if hasattr(sys, 'getandroidapilevel'):
+ return True
+ return False
+
+
+def is_abstract_socket_namespace(address):
+ if not address:
+ return False
+ if isinstance(address, bytes):
+ return address[0] == 0
+ elif isinstance(address, str):
+ return address[0] == "\0"
+ raise TypeError('address type of {address!r} unrecognized')
+
+
+abstract_sockets_supported = _platform_supports_abstract_sockets()
+
#
# Function returning a temp directory which will be removed on exit
#
diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py
index 18947170cbcdc..30ea23da69499 100644
--- a/Lib/test/_test_multiprocessing.py
+++ b/Lib/test/_test_multiprocessing.py
@@ -3140,6 +3140,19 @@ def test_context(self):
if self.TYPE == 'processes':
self.assertRaises(OSError, l.accept)
+ @unittest.skipUnless(util.abstract_sockets_supported,
+ "test needs abstract socket support")
+ def test_abstract_socket(self):
+ with self.connection.Listener("\0something") as listener:
+ with self.connection.Client(listener.address) as client:
+ with listener.accept() as d:
+ client.send(1729)
+ self.assertEqual(d.recv(), 1729)
+
+ if self.TYPE == 'processes':
+ self.assertRaises(OSError, listener.accept)
+
+
class _TestListenerClient(BaseTestCase):
ALLOWED_TYPES = ('processes', 'threads')
diff --git a/Misc/NEWS.d/next/Library/2020-03-09-01-45-06.bpo-39850.eaJNIE.rst b/Misc/NEWS.d/next/Library/2020-03-09-01-45-06.bpo-39850.eaJNIE.rst
new file mode 100644
index 0000000000000..57f98f5f0d6fb
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-03-09-01-45-06.bpo-39850.eaJNIE.rst
@@ -0,0 +1,2 @@
+:mod:`multiprocessing` now supports abstract socket addresses (if abstract sockets
+are supported in the running platform). Patch by Pablo Galindo.
More information about the Python-checkins
mailing list