Skip to content

Commit

Permalink
Fall back to select if poll does not exist
Browse files Browse the repository at this point in the history
select.poll will be missing when Gevent (or Eventlet, soon) monkey
patchiing is applied.

Closes: #78
  • Loading branch information
jstasiak committed Jan 7, 2016
1 parent 0f3f895 commit b22f460
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 2 deletions.
35 changes: 34 additions & 1 deletion python2/pyinotify.py
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,39 @@ def __init__(self, err):
PyinotifyError.__init__(self, err)


try:
_poll_class = select.poll
except AttributeError:
class _Poll(object):
"""
poll emulator implemented using select.
This is used to make the client code happy in case of select.poll missing.
Select.poll will be missing when Gevent or (soon) Eventlet monkey patching
is applied, see https://github.com/seb-m/pyinotify/issues/78.
"""
def __init__(self):
self._fds = []

def register(self, fd, eventmask):
assert eventmask == select.POLLIN, 'Only POLLIN supported right now'
self._fds.append(fd)

def poll(self, timeout):
timeout_in_seconds = timeout / 1000.0 if timeout is not None else None
can_read, _, _ = select.select(self._fds, [], [], timeout_in_seconds)
return [(fd, select.POLLIN) for fd in can_read]

def unregister(self, fd):
try:
self._fds.remove(fd)
except ValueError:
# poll.unregister is supposed to raise KeyError in case of
# attempting to unregister a descriptor that's not registered.
raise KeyError(fd)

_poll_class = _Poll

class Notifier:
"""
Read notifications, process events.
Expand Down Expand Up @@ -1138,7 +1171,7 @@ def __init__(self, watch_manager, default_proc_fun=None, read_freq=0,
# File descriptor
self._fd = self._watch_manager.get_fd()
# Poll object and registration
self._pollobj = select.poll()
self._pollobj = _poll_class()
self._pollobj.register(self._fd, select.POLLIN)
# This pipe is correctely initialized and used by ThreadedNotifier
self._pipe = (-1, -1)
Expand Down
36 changes: 35 additions & 1 deletion python3/pyinotify.py
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,40 @@ def __init__(self, err):
PyinotifyError.__init__(self, err)


try:
_poll_class = select.poll
except AttributeError:
class _Poll(object):
"""
poll emulator implemented using select.
This is used to make the client code happy in case of select.poll missing.
Select.poll will be missing when Gevent or (soon) Eventlet monkey patching
is applied, see https://github.com/seb-m/pyinotify/issues/78.
"""
def __init__(self):
self._fds = []

def register(self, fd, eventmask):
assert eventmask == select.POLLIN, 'Only POLLIN supported right now'
self._fds.append(fd)

def poll(self, timeout):
timeout_in_seconds = timeout / 1000.0 if timeout is not None else None
can_read, _, _ = select.select(self._fds, [], [], timeout_in_seconds)
return [(fd, select.POLLIN) for fd in can_read]

def unregister(self, fd):
try:
self._fds.remove(fd)
except ValueError:
# poll.unregister is supposed to raise KeyError in case of
# attempting to unregister a descriptor that's not registered.
raise KeyError(fd)

_poll_class = _Poll


class Notifier:
"""
Read notifications, process events.
Expand Down Expand Up @@ -1121,7 +1155,7 @@ def __init__(self, watch_manager, default_proc_fun=None, read_freq=0,
# File descriptor
self._fd = self._watch_manager.get_fd()
# Poll object and registration
self._pollobj = select.poll()
self._pollobj = _poll_class()
self._pollobj.register(self._fd, select.POLLIN)
# This pipe is correctely initialized and used by ThreadedNotifier
self._pipe = (-1, -1)
Expand Down

0 comments on commit b22f460

Please sign in to comment.