Loading...
Searching...
No Matches
libcamera::Thread Class Reference

A thread of execution. More...

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

## Public Member Functions

| Thread (std::string name={})
| Create a thread.
void | start ()
| Start the thread.
void | exit (int code=0)
| Stop the thread's event loop.
bool | wait (utils::duration duration=utils::duration::max())
| Wait for the thread to finish.
int | setThreadAffinity (const Span< const unsigned int > &cpus)
| Set the CPU affinity mask of the thread.
bool | isRunning ()
| Check if the thread is running.
EventDispatcher * | eventDispatcher ()
| Retrieve the event dispatcher.
void | dispatchMessages (Message::Type type=Message::Type::None, Object *receiver=nullptr)
| Dispatch posted messages for this thread.
void | removeMessages (Object *receiver)
| Remove all posted messages for the receiver.

## Static Public Member Functions

static Thread * | current ()
| Retrieve the Thread instance for the current thread.
static pid_t | currentId ()
| Retrieve the ID of the current thread.

## Public Attributes

Signal | finished
| Signal the end of thread execution.

## Protected Member Functions

int | exec ()
| Enter the event loop.
virtual void | run ()
| Main function of the thread.

## 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:

- The worker is the Thread performing work and being instructed to stop.
- The controller is the context which instructs the worker thread to stop.
- The other contexts are any threads other than the worker and controller that interact with the worker thread.

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,
|  | Object * | receiver = nullptr )

Dispatch posted messages for this thread.

Parameters

  [in] | type | The message type
  [in] | receiver | The receiver whose messages to dispatch

This function immediately dispatches all the messages of the given type previously posted to this thread for the receiver with postMessage(). If the type is Message::Type::None, all messages types are dispatched. If the receiver is null, messages to all receivers 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.

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] | 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.

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

## removeMessages()

void libcamera::Thread::removeMessages | ( | Object * | receiver | ) |

Remove all posted messages for the receiver.

Parameters

  [in] | receiver | The receiver

If the receiver is not bound to this thread the behaviour is undefined.

## run()

void libcamera::Thread::run | ( |  | ) |

protected virtual

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] | 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.

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] | 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.

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:

- include/libcamera/base/thread.h
- src/libcamera/base/thread.cpp