# 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.
vlog.dbg("%s on fd %d" % (s, fd))
def __reset(self):
- self.poll = select.poll()
+ self.poll = _SelectPoll()
self.timeout = -1