Skip to content

Commit

Permalink
Allow to call FSEventsEmitter.stop() twice without error
Browse files Browse the repository at this point in the history
  • Loading branch information
LKleinNux authored and BoboTiG committed Sep 19, 2018
1 parent f6d7683 commit e2730fd
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 2 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Gary van der Merwe <garyvdm@garyvdm.localdomain>
Gora Khargosh <gora.khargosh@gmail.com>
Hannu Valtonen <hannu.valtonen@ohmu.fi>
Jesse Printz <jesse@jonypawks.net>
Léa Klein <lklein@nuxeo.com>
Luke McCarthy <luke@iogopro.co.uk>
Lukáš Lalinský <lalinsky@gmail.com>
Malthe Borch <mborch@gmail.com>
Expand Down
6 changes: 4 additions & 2 deletions src/watchdog/observers/fsevents.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,10 @@ def __init__(self, event_queue, watch, timeout=DEFAULT_EMITTER_TIMEOUT):
self.snapshot = DirectorySnapshot(watch.path, watch.is_recursive)

def on_thread_stop(self):
_fsevents.remove_watch(self.watch)
_fsevents.stop(self)
if self.watch:
_fsevents.remove_watch(self.watch)
_fsevents.stop(self)
self._watch = None

def queue_events(self, timeout):
with self._lock:
Expand Down
64 changes: 64 additions & 0 deletions tests/test_fsevents.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# coding: utf-8
import logging
import os
from functools import partial

import pytest

from watchdog.observers.api import ObservedWatch
from tests import Queue

try:
from watchdog.observers.fsevents import FSEventsEmitter
except ImportError:
pytestmark = pytest.mark.skip("macOS only.")

from .shell import mkdtemp, rm

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)


def setup_function(function):
global p, event_queue
tmpdir = os.path.realpath(mkdtemp())
p = partial(os.path.join, tmpdir)
event_queue = Queue()


def teardown_function(function):
emitter.stop()
emitter.join(5)
rm(p(""), recursive=True)
assert not emitter.is_alive()


def start_watching(path=None, use_full_emitter=False):
global emitter
path = p("") if path is None else path
emitter = FSEventsEmitter(event_queue, ObservedWatch(path, recursive=True))
emitter.start()


def test_remove_watch_twice():
"""
ValueError: PyCapsule_GetPointer called with invalid PyCapsule object
The above exception was the direct cause of the following exception:
src/watchdog/utils/__init__.py:92: in stop
self.on_thread_stop()
src/watchdog/observers/fsevents.py:73: SystemError
def on_thread_stop(self):
> _fsevents.remove_watch(self.watch)
E SystemError: <built-in function remove_watch> returned a result with an error set
(FSEvents.framework) FSEventStreamStop(): failed assertion 'streamRef != NULL'
(FSEvents.framework) FSEventStreamInvalidate(): failed assertion 'streamRef != NULL'
(FSEvents.framework) FSEventStreamRelease(): failed assertion 'streamRef != NULL'
"""
start_watching()
# This one must work
emitter.stop()
# This is allowed to call several times .stop()
emitter.stop()

0 comments on commit e2730fd

Please sign in to comment.