eventlet/gevent doesn't work well with select.poll because it blocks.
So ovsdb python binding can't be used with eventlet/gevent.
So monkey patch to select.poll with a function that emulate select.poll
with select.select.

Signed-off-by: Isaku Yamahata <[email protected]>
---
 python/ovs/poller.py |   58 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 57 insertions(+), 1 deletions(-)

diff --git a/python/ovs/poller.py b/python/ovs/poller.py
index e459c58..3c9b4f2 100644
--- a/python/ovs/poller.py
+++ b/python/ovs/poller.py
@@ -12,10 +12,12 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import collections
 import errno
-import select
 import ovs.timeval
 import ovs.vlog
+import select
+import socket
 
 vlog = ovs.vlog.Vlog("poller")
 
@@ -124,3 +126,57 @@ class Poller(object):
     def __reset(self):
         self.poll = select.poll()
         self.timeout = -1
+
+
+class _SelectSelect(object):
+    """ select.poll emulation by using select.select."""
+    def __init__(self):
+        super(_SelectSelect, self).__init__()
+        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):
+        rlist, wlist, xlist = select.select(self.rlist, self.wlist, self.xlist,
+                                            timeout)
+        events_dict = collections.defaultdict(int)
+        for fd in rlist:
+            events_dict[fd] |= select.POLLIN
+        for fd in wlist:
+            events_dict[fd] |= select.POLLOUT
+        for fd in xlist:
+            events_dict[fd] |= (select.POLLERR | select.POLLHUP |
+                                select.POLLNFVAL)
+        return [(fd, events) for (fd, events) in events_dict.items()]
+
+
+_IS_PATCHED = False
+
+
+def monkey_patch():
+    """
+    patch select.poll for eventlet/gevent.
+    select.poll can't be used with eventlet/gevent because select.poll blocks
+    python interpreter. So they can't be used with green thread like greenlet.
+    """
+    global _IS_PATCHED
+    if _IS_PATCHED:
+        return
+    _IS_PATCHED = True
+
+    if hasattr(select, "poll"):
+        return
+    select.poll = _SelectSelect
-- 
1.7.1.1

_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev

Reply via email to