From 91a7865b6581cd8754da843e09edb97c138e97de Mon Sep 17 00:00:00 2001 From: Sergey Shepelev Date: Fri, 1 Feb 2013 04:25:18 +0400 Subject: [PATCH] greenio: Pre-cache proxied GreenSocket methods; Fixes Bitbucket #136; Thanks to Derk Tegeler https://bitbucket.org/which_linden/eventlet/issue/136 --- eventlet/greenio.py | 21 +++++++++++++++++---- tests/greenio_test.py | 6 ++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/eventlet/greenio.py b/eventlet/greenio.py index b6946e8..555d04c 100644 --- a/eventlet/greenio.py +++ b/eventlet/greenio.py @@ -143,15 +143,28 @@ class GreenSocket(object): # act non-blocking self.act_non_blocking = False + # Copy some attributes from underlying real socket. + # This is the easiest way that i found to fix + # https://bitbucket.org/which_linden/eventlet/issue/136 + # Only `getsockopt` is required to fix that issue, others + # are just premature optimization to save __getattr__ call. + self.bind = fd.bind + self.close = fd.close + self.fileno = fd.fileno + self.getsockname = fd.getsockname + self.getsockopt = fd.getsockopt + self.listen = fd.listen + self.setsockopt = fd.setsockopt + self.shutdown = fd.shutdown + @property def _sock(self): return self - #forward unknown attibutes to fd - # cache the value for future use. + # Forward unknown attributes to fd, cache the value for future use. # I do not see any simple attribute which could be changed - # so caching everything in self is fine, - # If we find such attributes - only attributes having __get__ might be cahed. + # so caching everything in self is fine. + # If we find such attributes - only attributes having __get__ might be cached. # For now - I do not want to complicate it. def __getattr__(self, name): attr = getattr(self.fd, name) diff --git a/tests/greenio_test.py b/tests/greenio_test.py index c15ebd5..4b70945 100644 --- a/tests/greenio_test.py +++ b/tests/greenio_test.py @@ -581,6 +581,12 @@ class TestGreenSocket(LimitedTestCase): flags = fcntl.fcntl(sock2.fd.fileno(), fcntl.F_GETFL) assert flags & os.O_NONBLOCK == 0 + def test_sockopt_interface(self): + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + assert sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR) == 0 + assert sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) == '\000' + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + class TestGreenPipe(LimitedTestCase): @skip_on_windows