Over the years we've used more and more threads in OpenLP for running things like web servers, downloads and other things that need to happen concurrently with the UI. Unfortunately because everything has been in bits and in various places, we've never had a unified way to run and keep track of threads. Thankfully we've largely not run into many issues, but in the lead up to version 3.0 we did start running into segfaults not just when OpenLP stopped, but also preventing OpenLP from starting.
New Threading API
When you want to create a thread, use this very simple thread API to ensure OpenLP knows about your thread.
Creating a thread:
from openlp.core.threading import ThreadWorker, run_thread class Worker(ThreadWorker): def start(self): """ Do your stuff in here, then emit the quit signal. """ self.server = Server() self.server.run() self.quit.emit() def stop(self): """ If your thread is long-running, this is how OpenLP will stop it if it is still running when the user exits OpenLP. """ self.server.stop() class MyClass(object): def run_server(self): """ Run the server in a thread """ worker = Worker() run_thread(worker, 'my_server')
Fetch the worker:
from openlp.core.threading import get_thread_worker def stop_server(): """ Stop the server """ worker = get_thread_worker('my_server') worker.stop()
Check if thread is finished:
from openlp.core.threading import is_thread_finished def monitor_server(): """ Check if the server is still running """ if is_thread_finished('my_server'): print('Server is stopped, uhoh!') else: print('Server is still running, all is good.')