Try to clean up the fds created by listenOnUnused that might leak

This commit is contained in:
Jean-Paul Calderone 2019-05-01 13:30:14 -04:00 committed by meejah
parent a431ea2241
commit b31acb790a

View File

@ -2,6 +2,10 @@
import os, re, socket, subprocess, errno import os, re, socket, subprocess, errno
from sys import platform from sys import platform
from zope.interface import implementer
import attr
# from Twisted # from Twisted
from twisted.python.reflect import requireModule from twisted.python.reflect import requireModule
from twisted.internet import defer, threads, reactor from twisted.internet import defer, threads, reactor
@ -10,7 +14,10 @@ from twisted.internet.error import CannotListenError
from twisted.python.procutils import which from twisted.python.procutils import which
from twisted.python import log from twisted.python import log
from twisted.internet.endpoints import AdoptedStreamServerEndpoint from twisted.internet.endpoints import AdoptedStreamServerEndpoint
from twisted.internet.interfaces import IReactorSocket from twisted.internet.interfaces import (
IReactorSocket,
IStreamServerEndpoint,
)
fcntl = requireModule("fcntl") fcntl = requireModule("fcntl")
@ -272,10 +279,8 @@ def _foolscapEndpointForPortNumber(portnum):
flags = fcntl.fcntl(fd, fcntl.F_GETFD) flags = fcntl.fcntl(fd, fcntl.F_GETFD)
flags = flags | os.O_NONBLOCK | fcntl.FD_CLOEXEC flags = flags | os.O_NONBLOCK | fcntl.FD_CLOEXEC
fcntl.fcntl(fd, fcntl.F_SETFD, flags) fcntl.fcntl(fd, fcntl.F_SETFD, flags)
return ( endpoint = AdoptedStreamServerEndpoint(reactor, fd, socket.AF_INET)
portnum, return (portnum, CleanupEndpoint(endpoint, fd))
AdoptedStreamServerEndpoint(reactor, fd, socket.AF_INET),
)
finally: finally:
s.close() s.close()
else: else:
@ -287,6 +292,22 @@ def _foolscapEndpointForPortNumber(portnum):
return (portnum, "tcp:%d" % (portnum,)) return (portnum, "tcp:%d" % (portnum,))
@implementer(IStreamServerEndpoint)
@attr.s
class CleanupEndpoint(object):
_wrapped = attr.ib()
_fd = attr.ib()
_listened = attr.ib(default=False)
def listen(self, protocolFactory):
self._listened = True
return self._wrapped.listen(protocolFactory)
def __del__(self):
if not self._listened:
os.close(self._fd)
def listenOnUnused(tub, portnum=None): def listenOnUnused(tub, portnum=None):
""" """
Start listening on an unused TCP port number with the given tub. Start listening on an unused TCP port number with the given tub.