libcamera
v0.4.0
Supporting cameras in Linux since 2019
|
A thread of execution. More...
Public Member Functions | |
Thread () | |
Create a thread. | |
void | start () |
Start the thread. | |
void | exit (int code=0) |
Stop the thread's event loop. More... | |
bool | wait (utils::duration duration=utils::duration::max()) |
Wait for the thread to finish. More... | |
int | setThreadAffinity (const Span< const unsigned int > &cpus) |
Set the CPU affinity mask of the thread. More... | |
bool | isRunning () |
Check if the thread is running. More... | |
EventDispatcher * | eventDispatcher () |
Retrieve the event dispatcher. More... | |
void | dispatchMessages (Message::Type type=Message::Type::None) |
Dispatch posted messages for this thread. More... | |
Static Public Member Functions | |
static Thread * | current () |
Retrieve the Thread instance for the current thread. More... | |
static pid_t | currentId () |
Retrieve the ID of the current thread. More... | |
Public Attributes | |
Signal | finished |
Signal the end of thread execution. | |
Protected Member Functions | |
int | exec () |
Enter the event loop. More... | |
virtual void | run () |
Main function of the thread. More... | |
Friends | |
class | Object |
class | ThreadData |
class | ThreadMain |
A thread of execution.
The Thread class is a wrapper around std::thread that handles integration with the Object, Signal and EventDispatcher classes.
Thread instances by default run an event loop until the exit() function is called. The event loop dispatches events (messages, notifiers and timers) sent to the objects living in the thread. This behaviour can be modified by overriding the run() function.
Threads can't be forcibly stopped. Instead, a thread user first requests the thread to exit and then waits for the thread's main function to react to the request and return, at which points the thread will stop.
For threads running exec(), the exit() function is used to request the thread to exit. For threads subclassing the Thread class and implementing a custom run() function, a subclass-specific mechanism shall be provided. In either case, the wait() function shall be called to wait for the thread to stop.
Due to their asynchronous nature, threads are subject to race conditions when they stop. This is of particular importance for messages posted to the thread with postMessage() (and the other mechanisms that rely on it, such as Object::invokeMethod() or asynchronous signal delivery). To understand the issues, three contexts need to be considered:
Messages posted to the worker thread from the controller context before calling exit() are queued to the thread's message queue, and the Thread class offers no guarantee that those messages will be processed before the thread stops. This allows threads to stop fast.
A thread that requires delivery of messages posted from the controller context before exit() should reimplement the run() function and call dispatchMessages() after exec().
Messages posted to the worker thread from the other contexts are asynchronous with respect to the exit() call from the controller context. There is no guarantee as to whether those messages will be processed or not before the thread stops.
Messages that are not processed will stay in the queue, in the exact same way as messages posted after the thread has stopped. They will be processed when the thread is restarted. If the thread is never restarted, they will be deleted without being processed when the Thread instance is destroyed.
|
static |
Retrieve the Thread instance for the current thread.
|
static |
Retrieve the ID of the current thread.
The thread ID corresponds to the Linux thread ID (TID) as returned by the gettid system call.
void libcamera::Thread::dispatchMessages | ( | Message::Type | type = Message::Type::None | ) |
Dispatch posted messages for this thread.
[in] | type | The message type |
This function immediately dispatches all the messages previously posted for this thread with postMessage() that match the message type. If the type is Message::Type::None, all messages are dispatched.
Messages shall only be dispatched from the current thread, typically within the thread from the run() function. Calling this function outside of the thread results in undefined behaviour.
This function is not thread-safe, but it may be called recursively in the same thread from an object's message handler. It guarantees delivery of messages in the order they have been posted in all cases.
EventDispatcher * libcamera::Thread::eventDispatcher | ( | ) |
Retrieve the event dispatcher.
This function retrieves the internal event dispatcher for the thread. The returned event dispatcher is valid until the thread is destroyed.
|
protected |
Enter the event loop.
This function enters an event loop based on the event dispatcher instance for the thread, and blocks until the exit() function is called. It is meant to be called within the thread from the run() function and shall not be called outside of the thread.
void libcamera::Thread::exit | ( | int | code = 0 | ) |
Stop the thread's event loop.
[in] | code | The exit code |
This function interrupts the event loop started by the exec() function, causing exec() to return code.
Calling exit() on a thread that reimplements the run() function and doesn't call exec() will likely have no effect.
bool libcamera::Thread::isRunning | ( | ) |
Check if the thread is running.
A Thread instance is considered as running once the underlying thread has started. This function guarantees that it returns true after the start() function returns, and false after the wait() function returns.
|
protectedvirtual |
Main function of the thread.
When the thread is started with start(), it calls this function in the context of the new thread. The run() function can be overridden to perform custom work, either custom initialization and cleanup before and after calling the Thread::exec() function, or a custom thread loop altogether. When this function returns the thread execution is stopped, and the finished signal is emitted.
Note that if this function is overridden and doesn't call Thread::exec(), no events will be dispatched to the objects living in the thread. These objects will not be able to use the EventNotifier, Timer or Message facilities. This includes functions that rely on message dispatching, such as Object::deleteLater().
The base implementation just calls exec().
Reimplemented in libcamera::ThreadMain.
int libcamera::Thread::setThreadAffinity | ( | const Span< const unsigned int > & | cpus | ) |
Set the CPU affinity mask of the thread.
[in] | cpus | The list of CPU indices that the thread is set affinity to |
The CPU indices should be within [0, std::thread::hardware_concurrency()). If any index is invalid, this function won't modify the thread affinity and will return an error.
bool libcamera::Thread::wait | ( | utils::duration | duration = utils::duration::max() | ) |
Wait for the thread to finish.
[in] | duration | Maximum wait duration |
This function waits until the thread finishes or the duration has elapsed, whichever happens first. If duration is equal to utils::duration::max(), the wait never times out. If the thread is not running the function returns immediately.