|
9 | 9 | import struct |
10 | 10 | import threading |
11 | 11 | from ctypes import c_char_p, c_int, c_uint32 |
12 | | -from functools import partial, reduce |
13 | | -from typing import TYPE_CHECKING, Any, Callable |
| 12 | +from functools import reduce |
| 13 | +from typing import TYPE_CHECKING |
14 | 14 |
|
15 | 15 | from watchdog.utils import UnsupportedLibcError |
16 | 16 |
|
@@ -150,16 +150,17 @@ def __init__(self, path: bytes, *, recursive: bool = False, event_mask: int | No |
150 | 150 | self._inotify_fd = inotify_fd |
151 | 151 | self._lock = threading.Lock() |
152 | 152 | self._closed = False |
153 | | - self._waiting_to_read = True |
| 153 | + self._is_reading = True |
154 | 154 | self._kill_r, self._kill_w = os.pipe() |
155 | 155 |
|
| 156 | + # _check_inotify_fd will return true if we can read _inotify_fd without blocking |
156 | 157 | if hasattr(select, "poll"): |
157 | 158 | self._poller = select.poll() |
158 | 159 | self._poller.register(self._inotify_fd, select.POLLIN) |
159 | 160 | self._poller.register(self._kill_r, select.POLLIN) |
160 | | - self._poll: Callable[[], Any] = partial(self._poller.poll) |
| 161 | + self._check_inotify_fd = lambda: any(fd == self._inotify_fd for fd, _ in self._poller.poll()) |
161 | 162 | else: |
162 | | - self._poll = partial(select.select, (self._inotify_fd, self._kill_r)) |
| 163 | + self._check_inotify_fd = lambda: self._inotify_fd in select.select([self._inotify_fd, self._kill_r], [], [])[0] |
163 | 164 |
|
164 | 165 | # Stores the watch descriptor for a given path. |
165 | 166 | self._wd_for_path: dict[bytes, int] = {} |
@@ -249,7 +250,7 @@ def close(self) -> None: |
249 | 250 | wd = self._wd_for_path[self._path] |
250 | 251 | inotify_rm_watch(self._inotify_fd, wd) |
251 | 252 |
|
252 | | - if self._waiting_to_read: |
| 253 | + if self._is_reading: |
253 | 254 | # inotify_rm_watch() should write data to _inotify_fd and wake |
254 | 255 | # the thread, but writing to the kill channel will gaurentee this |
255 | 256 | os.write(self._kill_w, b"!") |
@@ -298,18 +299,17 @@ def _recursive_simulate(src_path: bytes) -> list[InotifyEvent]: |
298 | 299 | if self._closed: |
299 | 300 | return [] |
300 | 301 |
|
301 | | - self._waiting_to_read = True |
| 302 | + self._is_reading = True |
302 | 303 |
|
303 | | - self._poll() |
| 304 | + if self._check_inotify_fd(): |
| 305 | + event_buffer = os.read(self._inotify_fd, event_buffer_size) |
304 | 306 |
|
305 | 307 | with self._lock: |
306 | | - self._waiting_to_read = False |
| 308 | + self._is_reading = False |
307 | 309 |
|
308 | 310 | if self._closed: |
309 | 311 | self._close_resources() |
310 | 312 | return [] |
311 | | - |
312 | | - event_buffer = os.read(self._inotify_fd, event_buffer_size) |
313 | 313 | except OSError as e: |
314 | 314 | if e.errno == errno.EINTR: |
315 | 315 | continue |
|
0 commit comments