Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

signal only works in main thread of the main interpreter #4

Open
finnito opened this issue Dec 21, 2020 · 1 comment
Open

signal only works in main thread of the main interpreter #4

finnito opened this issue Dec 21, 2020 · 1 comment

Comments

@finnito
Copy link

finnito commented Dec 21, 2020

Kia ora!

Thanks for the great wrapper. I am attempting to use fswatch and tkinter to monitor the filesystem and display a GUI of changes. The trickiness is that monitor.start() and window.mainloop() (from TK) are both blocking calls. The TK mainloop is also not threadsafe, and must be run from the main thread. Therefore, I am trying to use fswatch from a thread.

I am trying to do essentially this, where the boot()function calls monitor.start(), but it then crashes, raising the following exception.

def main():
    # This starts the fswatch monitor
    control_thread = Thread(target=boot, daemon=True)
    control_thread.start()
    
    # This starts the TK loop
    window.after(0, check_queue)
    window.mainloop()

def boot():
    monitor = Monitor()
    monitor.set_recursive()

    for directory in DIRECTORIES:
        monitor.add_path(directory["path"])

    monitor.set_callback(callback)
    monitor.start()

I'm not super good at this stuff, so any help would be appreciated!

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/threading.py", line 954, in _bootstrap_inner
    self.run()
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/threading.py", line 892, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/finnlesueur/Git/tooDo/tooDo.py", line 152, in boot
    monitor.start()
  File "/Users/finnlesueur/Git/tooDo/venv/lib/python3.9/site-packages/fswatch/fswatch.py", line 49, in start
    signal.signal(signal.SIGINT, self._handle_signal)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/signal.py", line 47, in signal
    handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
ValueError: signal only works in main thread of the main interpreter
@Feuermurmel
Copy link

Feuermurmel commented Jan 15, 2021

I have not yet run into this problem myself, but looking at the implementation of Monitor.start(), I think the only way to solve this problem is to remove the call to signal() completely. IMHO, there is no reason to set up a signal handler there. A monitor can be stopped by calling fsw_stop_monitor() from another thread so the signal handler (or an appropriate except KeyboardInterrupt:) can be installed on the main thread.

Edit:

I also ran into the problem. I'm currently using this subclass of Monitor, to solve the problem:

class _Monitor(fswatch.Monitor):
    def start(self):
        fswatch.libfswatch.fsw_start_monitor(self.handle)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants