X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=python%2Fovs%2Fpoller.py;h=7d15f3edb6a8b9cb3cde7b531898fdfc3925f627;hb=85b20fd6ee585f462e012fbcc7f966a81edab2ed;hp=e459c5823e9cd5ec7f79cffa3351fc1a0c4a222b;hpb=e368cad8ecf6dbf272b2a3775b2e3e5e2dc6a5cf;p=sliver-openvswitch.git diff --git a/python/ovs/poller.py b/python/ovs/poller.py index e459c5823..7d15f3edb 100644 --- a/python/ovs/poller.py +++ b/python/ovs/poller.py @@ -13,12 +13,76 @@ # limitations under the License. import errno -import select import ovs.timeval import ovs.vlog +import select +import socket vlog = ovs.vlog.Vlog("poller") +POLLIN = 0x001 +POLLOUT = 0x004 +POLLERR = 0x008 +POLLHUP = 0x010 +POLLNVAL = 0x020 + +# 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 & POLLIN: + self.rlist.append(fd) + events &= ~POLLIN + if events & POLLOUT: + self.wlist.append(fd) + events &= ~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) | POLLIN + for fd in wlist: + events_dict[fd] = events_dict.get(fd, 0) | POLLOUT + for fd in xlist: + events_dict[fd] = events_dict.get(fd, 0) | (POLLERR | + POLLHUP | + 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. @@ -109,18 +173,18 @@ class Poller(object): for fd, revents in events: if revents != 0: s = "" - if revents & select.POLLIN: + if revents & POLLIN: s += "[POLLIN]" - if revents & select.POLLOUT: + if revents & POLLOUT: s += "[POLLOUT]" - if revents & select.POLLERR: + if revents & POLLERR: s += "[POLLERR]" - if revents & select.POLLHUP: + if revents & POLLHUP: s += "[POLLHUP]" - if revents & select.POLLNVAL: + if revents & POLLNVAL: s += "[POLLNVAL]" vlog.dbg("%s on fd %d" % (s, fd)) def __reset(self): - self.poll = select.poll() + self.poll = SelectPoll() self.timeout = -1