From 539f82a30ec9268339cebd1440ac5b6314ecca02 Mon Sep 17 00:00:00 2001 From: "donovan.linden" Date: Mon, 31 Mar 2008 17:56:05 -0400 Subject: [PATCH] [svn r107] wrap_select_with_coroutine_select: This is to cooperate with people who are trying to do blocking reads with a timeout. This only works if r, w, and e aren't bigger than len 1, and if either r or w is populated. Install this with eventlet.util.wrap_select_with_coroutine_select, which makes the global select.select into fake_select. --- eventlet/selecthub.py | 3 ++- eventlet/util.py | 39 +++++++++++++++++++++++++++++++++++++++ eventlet/wrappedfd.py | 3 ++- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/eventlet/selecthub.py b/eventlet/selecthub.py index 60e2bb6..921cd4d 100644 --- a/eventlet/selecthub.py +++ b/eventlet/selecthub.py @@ -31,6 +31,7 @@ import time from bisect import insort, bisect_left from eventlet import greenlib +from eventlet import util from eventlet.runloop import RunLoop, Timer import greenlet @@ -157,7 +158,7 @@ class Hub(object): writers = self.writers excs = self.excs try: - r, w, ig = select.select(readers.keys(), writers.keys(), [], seconds) + r, w, ig = util.__original_select__(readers.keys(), writers.keys(), [], seconds) except select.error, e: if e.args[0] == errno.EINTR: return diff --git a/eventlet/util.py b/eventlet/util.py index 657716c..d0e7316 100644 --- a/eventlet/util.py +++ b/eventlet/util.py @@ -26,6 +26,7 @@ THE SOFTWARE. import os import fcntl import socket +import select import errno from errno import EWOULDBLOCK, EAGAIN @@ -75,6 +76,7 @@ def socket_connect(descriptor, address): __original_socket__ = socket.socket + def tcp_socket(): s = __original_socket__(socket.AF_INET, socket.SOCK_STREAM) set_nonblocking(s) @@ -112,6 +114,43 @@ def wrap_socket_with_coroutine_socket(): socket.ssl = wrap_ssl +__original_select__ = select.select + + +def fake_select(r, w, e, timeout): + """This is to cooperate with people who are trying to do blocking + reads with a timeout. This only works if r, w, and e aren't + bigger than len 1, and if either r or w is populated. + + Install this with wrap_select_with_coroutine_select, + which makes the global select.select into fake_select. + """ + from eventlet import api + + assert len(r) <= 1 + assert len(w) <= 1 + assert len(e) <= 1 + + if w and r: + raise RuntimeError('fake_select doesn\'t know how to do that yet') + + try: + if r: + api.trampoline(r[0], read=True, timeout=timeout) + return r, [], [] + else: + api.trampoline(w[0], write=True, timeout=timeout) + return [], w, [] + except api.TimeoutError, e: + return [], [], [] + except: + return [], [], e + + +def wrap_select_with_coroutine_select(): + select.select = fake_select + + def socket_bind_and_listen(descriptor, addr=('', 0), backlog=50): set_reuse_addr(descriptor) descriptor.bind(addr) diff --git a/eventlet/wrappedfd.py b/eventlet/wrappedfd.py index 21265fb..9175fdd 100644 --- a/eventlet/wrappedfd.py +++ b/eventlet/wrappedfd.py @@ -281,4 +281,5 @@ class wrapped_file(wrapped_fd): send = higher_order_send(util.file_send) def flush(self): - self.fd.flush() + fn = self.flush = self.fd.flush + return fn()