2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-05 00:35:33 +00:00

python/ovs/poller: use select.select instead of select.poll.

eventlet/gevent doesn't work well with select.poll because select.poll blocks
python interpreter as a whole instead of switching from the current thread
which is about to block to other runnable thread.
So ovsdb python binding can't be used with eventlet/gevent.
Emulate select.poll with select.select because using python means that
performance isn't so important.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Isaku Yamahata
2012-09-05 19:38:26 +09:00
committed by Ben Pfaff
parent 78a3fff6c3
commit ed815d9bd2

View File

@@ -13,13 +13,72 @@
# limitations under the License.
import errno
import select
import ovs.timeval
import ovs.vlog
import select
import socket
vlog = ovs.vlog.Vlog("poller")
# eventlet/gevent doesn't support select.poll. If select.poll is used,
# python interpreter is blocked as a whole instead of switching from the
# current thread that is about to block to other runnable thread.
# So emulate select.poll by select.select because using python means that
# performance isn't so important.
class _SelectSelect(object):
""" select.poll emulation by using select.select.
Only register and poll are needed at the moment.
"""
def __init__(self):
self.rlist = []
self.wlist = []
self.xlist = []
def register(self, fd, events):
if isinstance(fd, socket.socket):
fd = fd.fileno()
assert isinstance(fd, int)
if events & select.POLLIN:
self.rlist.append(fd)
events &= ~select.POLLIN
if events & select.POLLOUT:
self.wlist.append(fd)
events &= ~select.POLLOUT
if events:
self.xlist.append(fd)
def poll(self, timeout):
if timeout == -1:
# epoll uses -1 for infinite timeout, select uses None.
timeout = None
else:
timeout = float(timeout) / 1000
rlist, wlist, xlist = select.select(self.rlist, self.wlist, self.xlist,
timeout)
# collections.defaultdict is introduced by python 2.5 and
# XenServer uses python 2.4. We don't use it for XenServer.
# events_dict = collections.defaultdict(int)
# events_dict[fd] |= event
events_dict = {}
for fd in rlist:
events_dict[fd] = events_dict.get(fd, 0) | select.POLLIN
for fd in wlist:
events_dict[fd] = events_dict.get(fd, 0) | select.POLLOUT
for fd in xlist:
events_dict[fd] = events_dict.get(fd, 0) | (select.POLLERR |
select.POLLHUP |
select.POLLNVAL)
return events_dict.items()
_SelectPoll = _SelectSelect
# If eventlet/gevent isn't used, we can use select.poll by replacing
# _SelectPoll with select.poll class
# _SelectPoll = select.poll
class Poller(object):
"""High-level wrapper around the "poll" system call.
@@ -122,5 +181,5 @@ class Poller(object):
vlog.dbg("%s on fd %d" % (s, fd))
def __reset(self):
self.poll = select.poll()
self.poll = _SelectPoll()
self.timeout = -1