hubs: defang after remove; related to second simultaneous read issue

https://github.com/eventlet/eventlet/issues/94

We have to defang the listener after removing it from the hub

Otherwise we never actaully remove it from the hub and get a return of the
second simultanous read.

This should fix this issue.

Turn off __builtin__ monkey patching by default

The reason is that eventlet.greenio.GreenPipe tries to
adapt an original file f, and performs the following check
isinstance(f, file) f is an original file object with file
is now our file method. This fails causing TypeError

nova-api exercises this

Fix up zmq to use the extended add signature

Having heard no problems relating eventlet and zmq,
I'm not going to dive in and drop random pataches against
it. If the 'Second simultaneous *er' crops up against
zmw then we at least now have the machinery to
address it.
This commit is contained in:
Michael Kerrin
2014-06-25 09:13:02 +01:00
committed by Sergey Shepelev
parent da87716714
commit 8f98f8b634
5 changed files with 17 additions and 10 deletions

View File

@@ -76,9 +76,9 @@ def select(read_list, write_list, error_list, timeout=None):
try:
for k, v in six.iteritems(ds):
if v.get('read'):
listeners.append(hub.add(hub.READ, k, on_read))
listeners.append(hub.add(hub.READ, k, on_read, on_error, lambda x: None))
if v.get('write'):
listeners.append(hub.add(hub.WRITE, k, on_write))
listeners.append(hub.add(hub.WRITE, k, on_write, on_error, lambda x: None))
try:
return hub.switch()
finally:

View File

@@ -227,7 +227,11 @@ class Socket(_Socket):
_Socket_getsockopt(self, EVENTS)
hub = hubs.get_hub()
self.__dict__['_eventlet_listener'] = hub.add(hub.READ, self.getsockopt(FD), event)
self.__dict__['_eventlet_listener'] = hub.add(hub.READ,
self.getsockopt(FD),
event,
lambda _: None,
lambda: None)
@_wraps(_Socket.close)
def close(self, linger=None):

View File

@@ -180,8 +180,8 @@ class GreenSocket(object):
# socket here would be useful.
raise IOClosed()
try:
return trampoline(fd, read=True, timeout=self.gettimeout(),
timeout_exc=socket.timeout("timed out"),
return trampoline(fd, read=read, write=write, timeout=timeout,
timeout_exc=timeout_exc,
mark_as_closed=self._mark_as_closed)
except IOClosed:
# This socket's been obsoleted. De-fang it.
@@ -423,9 +423,9 @@ class _SocketDuckForFd(object):
# Don't trampoline if we're already closed.
raise IOClosed()
try:
return trampoline(fd, read=True, timeout=self.gettimeout(),
timeout_exc=socket.timeout("timed out"),
mark_as_closed=self.mark_as_closed)
return trampoline(fd, read=read, write=write, timeout=timeout,
timeout_exc=timeout_exc,
mark_as_closed=self._mark_as_closed)
except IOClosed:
# Our fileno has been obsoleted. Defang ourselves to
# prevent spurious closes.

View File

@@ -193,9 +193,9 @@ class BaseHub(object):
if fileno in bucket:
listener = bucket[fileno]
found = True
listener.defang()
self.closed.append(bucket[fileno])
self.closed.append(listener)
self.remove(listener)
listener.defang()
return found
@@ -210,6 +210,7 @@ class BaseHub(object):
if listener.spent:
# trampoline may trigger this in its finally section.
return
fileno = listener.fileno
evtype = listener.evtype
self.listeners[evtype].pop(fileno, None)

View File

@@ -227,6 +227,8 @@ def monkey_patch(**on):
if modname == 'MySQLdb':
# MySQLdb is only on when explicitly patched for the moment
on.setdefault(modname, False)
if modname == '__builtin__':
on.setdefault(modname, False)
on.setdefault(modname, default_on)
modules_to_patch = []