This is a partial revert of c1aa16d19, but keeps its test. Applications that use eventlet cannot use poll() without blocking. To fix an issue where the check_connection_completion() code would not detect connection errors when using select(), we switched to using the system poll() for checking the connection while leaving the select-based poller the default. This mixes monkeypatched and unpatched code and caused eventlet-based code to block every time we connect.
According to the connect(2) man page, you can detect connect() errors when using select(): After select(2) indicates writability, use getsockopt(2) to read the SO_ERROR option at level SOL_SOCKET to determine whether connect() completed successfully (SO_ERROR is zero) or unsuccessfully (SO_ERROR is one of the usual error codes listed here, explaining the reason for the failure) so this patch does that instead. Signed-off-by: Terry Wilson <[email protected]> --- python/ovs/poller.py | 35 ++--------------------------------- python/ovs/socket_util.py | 6 +++++- 2 files changed, 7 insertions(+), 34 deletions(-) diff --git a/python/ovs/poller.py b/python/ovs/poller.py index 3624ec865..7b3238d6d 100644 --- a/python/ovs/poller.py +++ b/python/ovs/poller.py @@ -31,22 +31,14 @@ except ImportError: SSL = None try: - from eventlet import patcher as eventlet_patcher + import eventlet.patcher def _using_eventlet_green_select(): - return eventlet_patcher.is_monkey_patched(select) + return eventlet.patcher.is_monkey_patched(select) except: - eventlet_patcher = None - def _using_eventlet_green_select(): return False -try: - from gevent import monkey as gevent_monkey -except: - gevent_monkey = None - - vlog = ovs.vlog.Vlog("poller") POLLIN = 0x001 @@ -265,26 +257,3 @@ class Poller(object): def __reset(self): self.poll = SelectPoll() self.timeout = -1 - - -def get_system_poll(): - """Returns the original select.poll() object. If select.poll is - monkey patched by eventlet or gevent library, it gets the original - select.poll and returns an object of it using the - eventlet.patcher.original/gevent.monkey.get_original functions. - - As a last resort, if there is any exception it returns the - SelectPoll() object. - """ - try: - if _using_eventlet_green_select(): - _system_poll = eventlet_patcher.original("select").poll - elif gevent_monkey and gevent_monkey.is_object_patched( - 'select', 'poll'): - _system_poll = gevent_monkey.get_original('select', 'poll') - else: - _system_poll = select.poll - except: - _system_poll = SelectPoll - - return _system_poll() diff --git a/python/ovs/socket_util.py b/python/ovs/socket_util.py index a73d6c6d7..0c322969a 100644 --- a/python/ovs/socket_util.py +++ b/python/ovs/socket_util.py @@ -174,7 +174,11 @@ def check_connection_completion(sock): pfds = p.poll(0) if len(pfds) == 1: revents = pfds[0][1] - if revents & ovs.poller.POLLERR or revents & ovs.poller.POLLHUP: + if revents & ovs.poller.POLLOUT: + # This is how select() indicates a connect() error + return sock.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) + elif revents & ovs.poller.POLLERR or revents & ovs.poller.POLLHUP: + # This is how poll() indicates a connect() error try: # The following should raise an exception. sock.send("\0", socket.MSG_DONTWAIT) -- 2.26.3 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
