Skip to content

Commit

Permalink
Merge pull request #374 from pR0Ps/master
Browse files Browse the repository at this point in the history
Fix crash on shutdown when root directory deleted.
  • Loading branch information
DonyorM committed Oct 26, 2016
2 parents 86e7250 + b692c5b commit 22c6055
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 4 deletions.
7 changes: 6 additions & 1 deletion src/watchdog/observers/inotify_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ def run(self):
IN_MOVE_TO event, remove the previous added matching IN_MOVE_FROM event
and add them back to the queue as a tuple.
"""
while self.should_keep_running():
deleted_self = False
while self.should_keep_running() and not deleted_self:
inotify_events = self._inotify.read_events()
for inotify_event in inotify_events:
logger.debug("in-event %s", inotify_event)
Expand All @@ -74,3 +75,7 @@ def matching_from_event(event):
else:
self._queue.put(inotify_event)

if inotify_event.is_delete_self and \
inotify_event.src_path == self._inotify.path:
# Deleted the watched directory, stop watching for events
deleted_self = True
5 changes: 3 additions & 2 deletions src/watchdog/observers/inotify_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,9 @@ def close(self):
Closes the inotify instance and removes all associated watches.
"""
with self._lock:
wd = self._wd_for_path[self._path]
inotify_rm_watch(self._inotify_fd, wd)
if self._path in self._wd_for_path:
wd = self._wd_for_path[self._path]
inotify_rm_watch(self._inotify_fd, wd)
os.close(self._inotify_fd)

def read_events(self, event_buffer_size=DEFAULT_EVENT_BUFFER_SIZE):
Expand Down
15 changes: 14 additions & 1 deletion tests/test_inotify_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import random
import pytest
from tests import tmpdir, p # pytest magic
from .shell import mkdir, touch, mv
from .shell import mkdir, touch, mv, rm
from watchdog.observers.api import ObservedWatch
from watchdog.utils import platform

Expand Down Expand Up @@ -104,6 +104,19 @@ def test_move_internal_batch(p):
inotify.close()


@pytest.mark.timeout(5)
def test_delete_watched_directory(p):
mkdir(p('dir'))
inotify = InotifyBuffer(p('dir').encode())
rm(p('dir'), recursive=True)

# Wait for the event to be picked up
inotify.read_event()

# Ensure InotifyBuffer shuts down cleanly without raising an exception
inotify.close()


def test_close_should_terminate_thread(p):
inotify = InotifyBuffer(p('').encode(), recursive=True)
assert inotify.is_alive()
Expand Down

0 comments on commit 22c6055

Please sign in to comment.