[5/5] libcamera: software_isp: Modify dispatching messages on stop
diff mbox series

Message ID 20250224120854.19747-6-mzamazal@redhat.com
State Superseded
Headers show
Series
  • Fix occasional software ISP assertion error on stop
Related show

Commit Message

Milan Zamazal Feb. 24, 2025, 12:08 p.m. UTC
There may be pending messages in SoftwareIsp message queue when
SoftwareIsp stops.  The call to IPAProxySoft::stop() will dispatch them
before SoftwareIsp::stop() finishes.  But this is dependent on
IPAProxySoft::stop() implementation and we can do better to ensure they
are dispatched before SoftwareIsp::stop() finishes.

Let's introduce new `receiver' argument to Thread::dispatchMessages(),
limiting dispatching the messages to the given receiver.  Now we can
flush the messages destined for the SoftwareIsp instance explicitly.
And the IPA proxy can flush just the messages destined for itself.
Other messages of the given thread remain queued and will be handled
elsewhere as appropriate.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
---
 include/libcamera/base/thread.h                    |  3 ++-
 src/libcamera/base/thread.cpp                      | 14 +++++++++-----
 src/libcamera/software_isp/software_isp.cpp        |  3 +++
 .../libcamera_templates/proxy_functions.tmpl       |  2 +-
 4 files changed, 15 insertions(+), 7 deletions(-)

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 02128f23..2fde2959 100644
--- a/src/libcamera/base/thread.cpp
+++ b/src/libcamera/base/thread.cpp
@@ -603,6 +603,8 @@  void Thread::removeMessages(Object *receiver)
 /**
  * \brief Dispatch posted messages for this thread
  * \param[in] type The message type
+ * \param[in] receiver If not null, dispatch only messages for the given
+ *    receiver
  *
  * This function immediately dispatches all the messages previously posted for
  * this thread with postMessage() that match the message \a type. If the \a type
@@ -616,7 +618,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());
 
@@ -640,12 +642,14 @@  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_;
+		if (receiver && receiver != messageReceiver)
+			continue;
+		ASSERT(data_ == messageReceiver->thread()->data_);
+		messageReceiver->pendingMessages_--;
 
 		locker.unlock();
-		receiver->message(message.get());
+		messageReceiver->message(message.get());
 		message.reset();
 		locker.lock();
 	}
diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp
index 3a605ab2..8f5ee774 100644
--- a/src/libcamera/software_isp/software_isp.cpp
+++ b/src/libcamera/software_isp/software_isp.cpp
@@ -13,6 +13,8 @@ 
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <libcamera/base/thread.h>
+
 #include <libcamera/controls.h>
 #include <libcamera/formats.h>
 #include <libcamera/stream.h>
@@ -339,6 +341,7 @@  void SoftwareIsp::stop()
 	ispWorkerThread_.wait();
 
 	running_ = false;
+	Thread::current()->dispatchMessages(Message::Type::InvokeMessage, this);
 	ipa_->stop();
 
 	for (auto buffer : queuedOutputBuffers_) {
diff --git a/utils/codegen/ipc/generators/libcamera_templates/proxy_functions.tmpl b/utils/codegen/ipc/generators/libcamera_templates/proxy_functions.tmpl
index b5797b14..25476990 100644
--- a/utils/codegen/ipc/generators/libcamera_templates/proxy_functions.tmpl
+++ b/utils/codegen/ipc/generators/libcamera_templates/proxy_functions.tmpl
@@ -34,7 +34,7 @@ 
 	thread_.exit();
 	thread_.wait();
 
-	Thread::current()->dispatchMessages(Message::Type::InvokeMessage);
+	Thread::current()->dispatchMessages(Message::Type::InvokeMessage, this);
 
 	state_ = ProxyStopped;
 {%- endmacro -%}