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
The explanation is in the comment in the code.

Closes: #78
  • Loading branch information
jstasiak committed Jan 7, 2016
1 parent 0f3f895 commit 04fea85
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 2 deletions.
37 changes: 36 additions & 1 deletion python2/pyinotify.py
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,41 @@ 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 is missing when Gevent monkey patching is applied, Eventlet
will soon start doing the same.
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 +1173,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
38 changes: 37 additions & 1 deletion python3/pyinotify.py
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,42 @@ 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 is missing when Gevent monkey patching is applied, Eventlet
will soon start doing the same.
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 +1157,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 04fea85

Please sign in to comment.