core: fix monster fork FD leak

_sockets only refers to the idle sockets list, it doesn't refer to every
socket currently in use by a Latch, for example, the 2*16 used by e.g.
Ansible's sleeping service pool.
pull/234/head
David Wilson 8 years ago
parent 7316c08237
commit c0ced6d04a

@ -981,6 +981,7 @@ class Latch(object):
closed = False closed = False
_waking = 0 _waking = 0
_sockets = [] _sockets = []
_allsockets = []
def __init__(self): def __init__(self):
self._lock = threading.Lock() self._lock = threading.Lock()
@ -989,10 +990,9 @@ class Latch(object):
@classmethod @classmethod
def _on_fork(cls): def _on_fork(cls):
while cls._sockets: cls._sockets = []
rsock, wsock = cls._sockets.pop() while cls._allsockets:
rsock.close() cls._allsockets.pop().close()
wsock.close()
def close(self): def close(self):
self._lock.acquire() self._lock.acquire()
@ -1015,6 +1015,7 @@ class Latch(object):
rsock, wsock = socket.socketpair() rsock, wsock = socket.socketpair()
set_cloexec(rsock.fileno()) set_cloexec(rsock.fileno())
set_cloexec(wsock.fileno()) set_cloexec(wsock.fileno())
self._allsockets.extend((rsock, wsock))
return rsock, wsock return rsock, wsock
def get(self, timeout=None, block=True): def get(self, timeout=None, block=True):

Loading…
Cancel
Save