Issue #12981: rewrite multiprocessing_{sendfd,recvfd} in Python.

This commit is contained in:
Charles-François Natali 2011-09-24 20:04:29 +02:00
parent 57e683e53e
commit dc863ddf79
3 changed files with 19 additions and 140 deletions

View file

@ -39,6 +39,7 @@ import os
import sys
import socket
import threading
import struct
import _multiprocessing
from multiprocessing import current_process
@ -51,7 +52,8 @@ from multiprocessing.connection import Client, Listener, Connection
#
#
if not(sys.platform == 'win32' or hasattr(_multiprocessing, 'recvfd')):
if not(sys.platform == 'win32' or (hasattr(socket, 'CMSG_LEN') and
hasattr(socket, 'SCM_RIGHTS'))):
raise ImportError('pickling of connections not supported')
#
@ -77,10 +79,23 @@ if sys.platform == 'win32':
else:
def send_handle(conn, handle, destination_pid):
_multiprocessing.sendfd(conn.fileno(), handle)
with socket.fromfd(conn.fileno(), socket.AF_UNIX, socket.SOCK_STREAM) as s:
s.sendmsg([b'x'], [(socket.SOL_SOCKET, socket.SCM_RIGHTS,
struct.pack("@i", handle))])
def recv_handle(conn):
return _multiprocessing.recvfd(conn.fileno())
size = struct.calcsize("@i")
with socket.fromfd(conn.fileno(), socket.AF_UNIX, socket.SOCK_STREAM) as s:
msg, ancdata, flags, addr = s.recvmsg(1, socket.CMSG_LEN(size))
try:
cmsg_level, cmsg_type, cmsg_data = ancdata[0]
if (cmsg_level == socket.SOL_SOCKET and
cmsg_type == socket.SCM_RIGHTS):
return struct.unpack("@i", cmsg_data[:size])[0]
except (ValueError, IndexError, struct.error):
pass
raise RuntimeError('Invalid data received')
#
# Support for a per-process server thread which caches pickled handles