Seems reasonable.  Some notes inline, mostly nits and questions.

On Tue, Sep 4, 2012 at 10:09 PM, 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>
> ---
> change v1 -> v2:
> - replace select.poll with select.select for simplicity instead of
>   monkey patching
> ---
>  python/ovs/poller.py |   71
> ++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 69 insertions(+), 2 deletions(-)
>
> diff --git a/python/ovs/poller.py b/python/ovs/poller.py
> index e459c58..e4294e3 100644
> --- a/python/ovs/poller.py
> +++ b/python/ovs/poller.py
> @@ -13,13 +13,80 @@
>  # 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 that does monkey patch to select module doesn't support

Is monkey patch still in comment on purpose?


+# 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 python is used so that
> +# performance isn't so important.
>



> +# If eventlet/gevent isn't used, we can use select.poll by replacing
> +# SelectPoll with select.poll class
> +# SelectPoll = select.poll
>
I would put this comment down by the line that says "SelectPoll =
_SelectSelect"



> +class _SelectSelect(object):
> +    """ select.poll emulation by using select.select.
> +    Only register and poll are needed at the moment.
> +    """
> +    def __init__(self):
>



> +        super(_SelectSelect, self).__init__()
>
This makes me think you are trying to something clever, when (I believe)
you are not.  Was there any particular reason to include it?


> +        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
>
I assume this is more typical to write it as this general form than as
 events -= select.POLLIN
which is equivalent since you're already in the conditional


> +        if events & select.POLLOUT:
> +            self.wlist.append(fd)
> +            events &= ~select.POLLOUT
> +        if events:
> +            self.xlist.append(fd)
> +
> +    @staticmethod
> +    def _events_update(events_dict, fd, event):
> +        """Emulate 'collections.defaultdict(int)[fd] |= event' with
> dict"""
>



> +        events = events_dict.setdefault(fd, 0)
> +        events_dict[fd] = events | event
>
Seems fine, could also be
  events_dict[fd] = events_dict.get(fd, 0) | event


+
> +    def poll(self, timeout):
> +        if timeout == -1:
>



> +            # epoll uses -1 for indifinite timeout, select uses None.
>
I think
  s/indifinite/infinite/


> +            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:
> +            self._events_update(events_dict, fd, select.POLLIN)
> +        for fd in wlist:
> +            self._events_update(events_dict, fd, select.POLLOUT)
> +        for fd in xlist:
> +            self._events_update(events_dict, fd, select.POLLERR |
> +                                select.POLLHUP | select.POLLNVAL)
>



> +        return [(fd, events) for (fd, events) in events_dict.items()]
>
This can just be
  return events_dict.items()
and save the noop list comprehension.  If you're worried about the
return value being confusing, could add a comment like
  # Returns a list of (fd, events) tuples

+
> +
> +SelectPoll = _SelectSelect
> +# SelectPoll = select.poll
>
Did you deliberately not add a _ to SelectPoll?  I didn't see any
external users, and they could always check Poller.poll if they needed
to see what version it was using.


> +
> +
>  class Poller(object):
>      """High-level wrapper around the "poll" system call.
>
> @@ -122,5 +189,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
>
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to