libcamera  v0.4.0
Supporting cameras in Linux since 2019
Public Member Functions | Static Public Member Functions | Public Attributes | Protected Member Functions | Friends | List of all members
libcamera::Thread Class Reference

A thread of execution. More...

Inheritance diagram for libcamera::Thread:
Inheritance graph
[legend]
Collaboration diagram for libcamera::Thread:
Collaboration graph
[legend]

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...
 
EventDispatchereventDispatcher ()
 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 Threadcurrent ()
 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
 

Detailed Description

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.

Stopping Threads

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.

Member Function Documentation

◆ current()

Thread * libcamera::Thread::current ( )
static

Retrieve the Thread instance for the current thread.

Thread Safety:
This function is thread-safe.
Returns
The Thread instance for the current thread

◆ currentId()

pid_t libcamera::Thread::currentId ( )
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.

Thread Safety:
This function is thread-safe.
Returns
The ID of the current thread

◆ dispatchMessages()

void libcamera::Thread::dispatchMessages ( Message::Type  type = Message::Type::None)

Dispatch posted messages for this thread.

Parameters
[in]typeThe 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()

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.

Thread Safety:
This function is thread-safe.
Returns
Pointer to the event dispatcher

◆ exec()

int libcamera::Thread::exec ( )
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.

Returns
The exit code passed to the exit() function

◆ exit()

void libcamera::Thread::exit ( int  code = 0)

Stop the thread's event loop.

Parameters
[in]codeThe 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.

Thread Safety:
This function is thread-safe.

◆ isRunning()

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.

Thread Safety:
This function is thread-safe.
Returns
True if the thread is running, false otherwise

◆ run()

void libcamera::Thread::run ( )
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.

◆ setThreadAffinity()

int libcamera::Thread::setThreadAffinity ( const Span< const unsigned int > &  cpus)

Set the CPU affinity mask of the thread.

Parameters
[in]cpusThe 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.

Returns
0 if all indices are valid, -EINVAL otherwise

◆ wait()

bool libcamera::Thread::wait ( utils::duration  duration = utils::duration::max())

Wait for the thread to finish.

Parameters
[in]durationMaximum 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.

Thread Safety:
This function is thread-safe.
Returns
True if the thread has finished, or false if the wait timed out

The documentation for this class was generated from the following files: