libcamera: base: thread: Support dispatching for a specific receiver

The Thread::dispatchMessage() function supports filtering messages based
on their type. It can be useful to also dispatch only messages posted
for a specific receiver. Add an optional receiver argument to the
dispatchMessage() function to do so. When set to null (the default
value), the behaviour of the function is not changed.

This facility is actually used in followup patches.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Milan Zamazal 2025-02-25 16:06:10 +01:00 committed by Kieran Bingham
parent cd32e069ec
commit 72a890e11a
2 changed files with 15 additions and 9 deletions

View file

@ -48,7 +48,8 @@ public:
EventDispatcher *eventDispatcher(); EventDispatcher *eventDispatcher();
void dispatchMessages(Message::Type type = Message::Type::None); void dispatchMessages(Message::Type type = Message::Type::None,
Object *receiver = nullptr);
protected: protected:
int exec(); int exec();

View file

@ -604,10 +604,12 @@ void Thread::removeMessages(Object *receiver)
/** /**
* \brief Dispatch posted messages for this thread * \brief Dispatch posted messages for this thread
* \param[in] type The message type * \param[in] type The message type
* \param[in] receiver The receiver whose messages to dispatch
* *
* This function immediately dispatches all the messages previously posted for * This function immediately dispatches all the messages of the given \a type
* this thread with postMessage() that match the message \a type. If the \a type * previously posted to this thread for the \a receiver with postMessage(). If
* is Message::Type::None, all messages are dispatched. * the \a type is Message::Type::None, all messages types are dispatched. If the
* \a receiver is null, messages to all receivers are dispatched.
* *
* Messages shall only be dispatched from the current thread, typically within * Messages shall only be dispatched from the current thread, typically within
* the thread from the run() function. Calling this function outside of the * the thread from the run() function. Calling this function outside of the
@ -617,7 +619,7 @@ void Thread::removeMessages(Object *receiver)
* same thread from an object's message handler. It guarantees delivery of * same thread from an object's message handler. It guarantees delivery of
* messages in the order they have been posted in all cases. * messages in the order they have been posted in all cases.
*/ */
void Thread::dispatchMessages(Message::Type type) void Thread::dispatchMessages(Message::Type type, Object *receiver)
{ {
ASSERT(data_ == ThreadData::current()); ASSERT(data_ == ThreadData::current());
@ -634,6 +636,9 @@ void Thread::dispatchMessages(Message::Type type)
if (type != Message::Type::None && msg->type() != type) if (type != Message::Type::None && msg->type() != type)
continue; continue;
if (receiver && receiver != msg->receiver_)
continue;
/* /*
* Move the message, setting the entry in the list to null. It * Move the message, setting the entry in the list to null. It
* will cause recursive calls to ignore the entry, and the erase * will cause recursive calls to ignore the entry, and the erase
@ -641,12 +646,12 @@ void Thread::dispatchMessages(Message::Type type)
*/ */
std::unique_ptr<Message> message = std::move(msg); std::unique_ptr<Message> message = std::move(msg);
Object *receiver = message->receiver_; Object *messageReceiver = message->receiver_;
ASSERT(data_ == receiver->thread()->data_); ASSERT(data_ == messageReceiver->thread()->data_);
receiver->pendingMessages_--; messageReceiver->pendingMessages_--;
locker.unlock(); locker.unlock();
receiver->message(message.get()); messageReceiver->message(message.get());
message.reset(); message.reset();
locker.lock(); locker.lock();
} }