Issue #14666: stop multiprocessing's resource-sharing thread after the tests are done.

Also, block delivery of signals to that thread. Patch by Richard Oudkerk.

This will hopefully fix sporadic freezes on the FreeBSD 9.0 buildbot.
This commit is contained in:
Antoine Pitrou 2012-04-27 23:51:03 +02:00
parent d0880d57b0
commit 92ff4e196b
2 changed files with 33 additions and 1 deletions

View file

@ -40,6 +40,7 @@
import socket
import threading
import struct
import signal
from multiprocessing import current_process
from multiprocessing.util import register_after_fork, debug, sub_debug
@ -209,6 +210,7 @@ def __init__(self):
self._lock = threading.Lock()
self._listener = None
self._address = None
self._thread = None
register_after_fork(self, ResourceSharer._afterfork)
def register(self, send, close):
@ -227,6 +229,24 @@ def get_connection(ident):
c.send((key, os.getpid()))
return c
def stop(self, timeout=None):
from .connection import Client
with self._lock:
if self._address is not None:
c = Client(self._address, authkey=current_process().authkey)
c.send(None)
c.close()
self._thread.join(timeout)
if self._thread.is_alive():
sub_warn('ResourceSharer thread did not stop when asked')
self._listener.close()
self._thread = None
self._address = None
self._listener = None
for key, (send, close) in self._cache.items():
close()
self._cache.clear()
def _afterfork(self):
for key, (send, close) in self._cache.items():
close()
@ -239,6 +259,7 @@ def _afterfork(self):
self._listener.close()
self._listener = None
self._address = None
self._thread = None
def _start(self):
from .connection import Listener
@ -249,12 +270,18 @@ def _start(self):
t = threading.Thread(target=self._serve)
t.daemon = True
t.start()
self._thread = t
def _serve(self):
if hasattr(signal, 'pthread_sigmask'):
signal.pthread_sigmask(signal.SIG_BLOCK, range(1, signal.NSIG))
while 1:
try:
conn = self._listener.accept()
key, destination_pid = conn.recv()
msg = conn.recv()
if msg is None:
break
key, destination_pid = msg
send, close = self._cache.pop(key)
send(conn, destination_pid)
close()

View file

@ -1965,6 +1965,11 @@ class _TestPicklingConnections(BaseTestCase):
ALLOWED_TYPES = ('processes',)
@classmethod
def tearDownClass(cls):
from multiprocessing.reduction import resource_sharer
resource_sharer.stop(timeout=5)
@classmethod
def _listener(cls, conn, families):
for fam in families: