+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
+