[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.
This commit is contained in:
@@ -31,6 +31,7 @@ import time
|
|||||||
from bisect import insort, bisect_left
|
from bisect import insort, bisect_left
|
||||||
|
|
||||||
from eventlet import greenlib
|
from eventlet import greenlib
|
||||||
|
from eventlet import util
|
||||||
from eventlet.runloop import RunLoop, Timer
|
from eventlet.runloop import RunLoop, Timer
|
||||||
|
|
||||||
import greenlet
|
import greenlet
|
||||||
@@ -157,7 +158,7 @@ class Hub(object):
|
|||||||
writers = self.writers
|
writers = self.writers
|
||||||
excs = self.excs
|
excs = self.excs
|
||||||
try:
|
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:
|
except select.error, e:
|
||||||
if e.args[0] == errno.EINTR:
|
if e.args[0] == errno.EINTR:
|
||||||
return
|
return
|
||||||
|
@@ -26,6 +26,7 @@ THE SOFTWARE.
|
|||||||
import os
|
import os
|
||||||
import fcntl
|
import fcntl
|
||||||
import socket
|
import socket
|
||||||
|
import select
|
||||||
import errno
|
import errno
|
||||||
from errno import EWOULDBLOCK, EAGAIN
|
from errno import EWOULDBLOCK, EAGAIN
|
||||||
|
|
||||||
@@ -75,6 +76,7 @@ def socket_connect(descriptor, address):
|
|||||||
|
|
||||||
__original_socket__ = socket.socket
|
__original_socket__ = socket.socket
|
||||||
|
|
||||||
|
|
||||||
def tcp_socket():
|
def tcp_socket():
|
||||||
s = __original_socket__(socket.AF_INET, socket.SOCK_STREAM)
|
s = __original_socket__(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
set_nonblocking(s)
|
set_nonblocking(s)
|
||||||
@@ -112,6 +114,43 @@ def wrap_socket_with_coroutine_socket():
|
|||||||
socket.ssl = wrap_ssl
|
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):
|
def socket_bind_and_listen(descriptor, addr=('', 0), backlog=50):
|
||||||
set_reuse_addr(descriptor)
|
set_reuse_addr(descriptor)
|
||||||
descriptor.bind(addr)
|
descriptor.bind(addr)
|
||||||
|
@@ -281,4 +281,5 @@ class wrapped_file(wrapped_fd):
|
|||||||
send = higher_order_send(util.file_send)
|
send = higher_order_send(util.file_send)
|
||||||
|
|
||||||
def flush(self):
|
def flush(self):
|
||||||
self.fd.flush()
|
fn = self.flush = self.fd.flush
|
||||||
|
return fn()
|
||||||
|
Reference in New Issue
Block a user