Thanks for humoring me, looks good. On Sep 5, 2555 BE, at 3:38, Isaku Yamahata <yamah...@valinux.co.jp> wrote:
> 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 <yamah...@valinux.co.jp> > --- > changes v2 -> v3: > - minor nit picks > > change v1 -> v2: > - replace select.poll with select.select for simplicity instead of > monkey patching > --- > 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 e459c58..5c89f23 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 > -- > 1.7.1.1 > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev