Issue #405: GreenSocket.accept does not notify_open (#406)

greenio: GreenSocket.accept does not notify_open

https://github.com/eventlet/eventlet/issues/405
This commit is contained in:
orishoshan 2017-04-17 12:04:26 +03:00 committed by Sergey Shepelev
parent fa87d41375
commit 38fd8a7131
2 changed files with 69 additions and 1 deletions

View File

@ -212,13 +212,16 @@ class GreenSocket(object):
def accept(self):
if self.act_non_blocking:
return self.fd.accept()
res = self.fd.accept()
notify_opened(res[0].fileno())
return res
fd = self.fd
_timeout_exc = socket_timeout('timed out')
while True:
res = socket_accept(fd)
if res is not None:
client, addr = res
notify_opened(client.fileno())
set_nonblocking(client)
return type(self)(client), addr
self._trampoline(fd, read=True, timeout=self.gettimeout(), timeout_exc=_timeout_exc)

View File

@ -18,6 +18,7 @@ from eventlet.hubs import get_hub
from eventlet.green import select, socket, time, ssl
from eventlet.support import capture_stderr, get_errno, six
import tests
import tests.mock as mock
def bufsized(sock, size=1):
@ -321,6 +322,70 @@ class TestGreenSocket(tests.LimitedTestCase):
killer.wait()
def test_blocking_accept_mark_as_reopened(self):
evt_hub = get_hub()
with mock.patch.object(evt_hub, "mark_as_reopened") as patched_mark_as_reopened:
def connect_once(listener):
# delete/overwrite the original conn
# object, only keeping the file object around
# closing the file object should close everything
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', listener.getsockname()[1]))
client.close()
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(('127.0.0.1', 0))
server.listen(50)
acceptlet = eventlet.spawn(connect_once, server)
conn, addr = server.accept()
conn.sendall(b'hello\n')
connfileno = conn.fileno()
conn.close()
assert patched_mark_as_reopened.called
assert patched_mark_as_reopened.call_count == 3, "3 fds were opened, but the hub was " \
"only notified {call_count} times" \
.format(call_count=patched_mark_as_reopened.call_count)
args, kwargs = patched_mark_as_reopened.call_args
assert args == (connfileno,), "Expected mark_as_reopened to be called " \
"with {expected_fileno}, but it was called " \
"with {fileno}".format(expected_fileno=connfileno,
fileno=args[0])
server.close()
def test_nonblocking_accept_mark_as_reopened(self):
evt_hub = get_hub()
with mock.patch.object(evt_hub, "mark_as_reopened") as patched_mark_as_reopened:
def connect_once(listener):
# delete/overwrite the original conn
# object, only keeping the file object around
# closing the file object should close everything
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', listener.getsockname()[1]))
client.close()
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(('127.0.0.1', 0))
server.listen(50)
server.setblocking(False)
acceptlet = eventlet.spawn(connect_once, server)
out = select.select([server], [], [])
conn, addr = server.accept()
conn.sendall(b'hello\n')
connfileno = conn.fileno()
conn.close()
assert patched_mark_as_reopened.called
assert patched_mark_as_reopened.call_count == 3, "3 fds were opened, but the hub was " \
"only notified {call_count} times" \
.format(call_count=patched_mark_as_reopened.call_count)
args, kwargs = patched_mark_as_reopened.call_args
assert args == (connfileno,), "Expected mark_as_reopened to be called " \
"with {expected_fileno}, but it was called " \
"with {fileno}".format(expected_fileno=connfileno,
fileno=args[0])
server.close()
def test_full_duplex(self):
large_data = b'*' * 10 * min_buf_size()
listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)