diff options
author | Isaku Yamahata <yamahata@valinux.co.jp> | 2012-09-05 19:38:26 +0900 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2012-09-05 09:10:44 -0700 |
commit | ed815d9bd28422a490fe370d7804d24bcd676806 (patch) | |
tree | 72645159cd1b85c176cbb085467c71636934f484 /python | |
parent | 78a3fff6c3b2f7943bcfd7301c666934834d2a0e (diff) |
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>
Diffstat (limited to 'python')
-rw-r--r-- | python/ovs/poller.py | 63 |
1 files changed, 61 insertions, 2 deletions
diff --git a/python/ovs/poller.py b/python/ovs/poller.py index e459c582..5c89f231 100644 --- a/python/ovs/poller.py +++ b/python/ovs/poller.py @@ -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 |