[v3,4/6] libcamera: base: thread: Support dispatching for a specific receiver
diff mbox series

Message ID 20250225150614.20195-5-mzamazal@redhat.com
State Accepted
Headers show
Series
  • Fix occasional software ISP assertion error on stop
Related show

Commit Message

Milan Zamazal Feb. 25, 2025, 3:06 p.m. UTC
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>
---
 include/libcamera/base/thread.h |  3 ++-
 src/libcamera/base/thread.cpp   | 21 +++++++++++++--------
 2 files changed, 15 insertions(+), 9 deletions(-)

Comments

Laurent Pinchart Feb. 26, 2025, 12:05 a.m. UTC | #1
Hi Milan,

Thank you for the patch.

On Tue, Feb 25, 2025 at 04:06:10PM +0100, Milan Zamazal wrote:
> 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>

> ---
>  include/libcamera/base/thread.h |  3 ++-
>  src/libcamera/base/thread.cpp   | 21 +++++++++++++--------
>  2 files changed, 15 insertions(+), 9 deletions(-)
> 
> diff --git a/include/libcamera/base/thread.h b/include/libcamera/base/thread.h
> index 3cbf6398..b9284c2c 100644
> --- a/include/libcamera/base/thread.h
> +++ b/include/libcamera/base/thread.h
> @@ -48,7 +48,8 @@ public:
>  
>  	EventDispatcher *eventDispatcher();
>  
> -	void dispatchMessages(Message::Type type = Message::Type::None);
> +	void dispatchMessages(Message::Type type = Message::Type::None,
> +			      Object *receiver = nullptr);
>  
>  protected:
>  	int exec();
> diff --git a/src/libcamera/base/thread.cpp b/src/libcamera/base/thread.cpp
> index 319bfda9..4de356c7 100644
> --- a/src/libcamera/base/thread.cpp
> +++ b/src/libcamera/base/thread.cpp
> @@ -604,10 +604,12 @@ void Thread::removeMessages(Object *receiver)
>  /**
>   * \brief Dispatch posted messages for this thread
>   * \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 thread with postMessage() that match the message \a type. If the \a type
> - * is Message::Type::None, all messages are dispatched.
> + * This function immediately dispatches all the messages of the given \a type
> + * previously posted to this thread for the \a receiver with postMessage(). If
> + * 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
>   * 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
>   * 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());
>  
> @@ -634,6 +636,9 @@ void Thread::dispatchMessages(Message::Type type)
>  		if (type != Message::Type::None && msg->type() != type)
>  			continue;
>  
> +		if (receiver && receiver != msg->receiver_)
> +			continue;
> +
>  		/*
>  		 * Move the message, setting the entry in the list to null. It
>  		 * 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);
>  
> -		Object *receiver = message->receiver_;
> -		ASSERT(data_ == receiver->thread()->data_);
> -		receiver->pendingMessages_--;
> +		Object *messageReceiver = message->receiver_;
> +		ASSERT(data_ == messageReceiver->thread()->data_);
> +		messageReceiver->pendingMessages_--;
>  
>  		locker.unlock();
> -		receiver->message(message.get());
> +		messageReceiver->message(message.get());
>  		message.reset();
>  		locker.lock();
>  	}
Kieran Bingham March 1, 2025, 10:56 p.m. UTC | #2
Quoting Milan Zamazal (2025-02-25 15:06:10)
> 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.
> 

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>

> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
> ---
>  include/libcamera/base/thread.h |  3 ++-
>  src/libcamera/base/thread.cpp   | 21 +++++++++++++--------
>  2 files changed, 15 insertions(+), 9 deletions(-)
> 
> diff --git a/include/libcamera/base/thread.h b/include/libcamera/base/thread.h
> index 3cbf6398..b9284c2c 100644
> --- a/include/libcamera/base/thread.h
> +++ b/include/libcamera/base/thread.h
> @@ -48,7 +48,8 @@ public:
>  
>         EventDispatcher *eventDispatcher();
>  
> -       void dispatchMessages(Message::Type type = Message::Type::None);
> +       void dispatchMessages(Message::Type type = Message::Type::None,
> +                             Object *receiver = nullptr);
>  
>  protected:
>         int exec();
> diff --git a/src/libcamera/base/thread.cpp b/src/libcamera/base/thread.cpp
> index 319bfda9..4de356c7 100644
> --- a/src/libcamera/base/thread.cpp
> +++ b/src/libcamera/base/thread.cpp
> @@ -604,10 +604,12 @@ void Thread::removeMessages(Object *receiver)
>  /**
>   * \brief Dispatch posted messages for this thread
>   * \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 thread with postMessage() that match the message \a type. If the \a type
> - * is Message::Type::None, all messages are dispatched.
> + * This function immediately dispatches all the messages of the given \a type
> + * previously posted to this thread for the \a receiver with postMessage(). If
> + * 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
>   * 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
>   * 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());
>  
> @@ -634,6 +636,9 @@ void Thread::dispatchMessages(Message::Type type)
>                 if (type != Message::Type::None && msg->type() != type)
>                         continue;
>  
> +               if (receiver && receiver != msg->receiver_)
> +                       continue;
> +
>                 /*
>                  * Move the message, setting the entry in the list to null. It
>                  * 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);
>  
> -               Object *receiver = message->receiver_;
> -               ASSERT(data_ == receiver->thread()->data_);
> -               receiver->pendingMessages_--;
> +               Object *messageReceiver = message->receiver_;
> +               ASSERT(data_ == messageReceiver->thread()->data_);
> +               messageReceiver->pendingMessages_--;
>  
>                 locker.unlock();
> -               receiver->message(message.get());
> +               messageReceiver->message(message.get());
>                 message.reset();
>                 locker.lock();
>         }
> -- 
> 2.48.1
>

Patch
diff mbox series

diff --git a/include/libcamera/base/thread.h b/include/libcamera/base/thread.h
index 3cbf6398..b9284c2c 100644
--- a/include/libcamera/base/thread.h
+++ b/include/libcamera/base/thread.h
@@ -48,7 +48,8 @@  public:
 
 	EventDispatcher *eventDispatcher();
 
-	void dispatchMessages(Message::Type type = Message::Type::None);
+	void dispatchMessages(Message::Type type = Message::Type::None,
+			      Object *receiver = nullptr);
 
 protected:
 	int exec();
diff --git a/src/libcamera/base/thread.cpp b/src/libcamera/base/thread.cpp
index 319bfda9..4de356c7 100644
--- a/src/libcamera/base/thread.cpp
+++ b/src/libcamera/base/thread.cpp
@@ -604,10 +604,12 @@  void Thread::removeMessages(Object *receiver)
 /**
  * \brief Dispatch posted messages for this thread
  * \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 thread with postMessage() that match the message \a type. If the \a type
- * is Message::Type::None, all messages are dispatched.
+ * This function immediately dispatches all the messages of the given \a type
+ * previously posted to this thread for the \a receiver with postMessage(). If
+ * 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
  * 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
  * 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());
 
@@ -634,6 +636,9 @@  void Thread::dispatchMessages(Message::Type type)
 		if (type != Message::Type::None && msg->type() != type)
 			continue;
 
+		if (receiver && receiver != msg->receiver_)
+			continue;
+
 		/*
 		 * Move the message, setting the entry in the list to null. It
 		 * 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);
 
-		Object *receiver = message->receiver_;
-		ASSERT(data_ == receiver->thread()->data_);
-		receiver->pendingMessages_--;
+		Object *messageReceiver = message->receiver_;
+		ASSERT(data_ == messageReceiver->thread()->data_);
+		messageReceiver->pendingMessages_--;
 
 		locker.unlock();
-		receiver->message(message.get());
+		messageReceiver->message(message.get());
 		message.reset();
 		locker.lock();
 	}