[libcamera-devel] [PATCH] android: camera_worker: Process all queued requests when stopping

Laurent Pinchart laurent.pinchart at ideasonboard.com
Sun May 23 04:33:42 CEST 2021


When stopping the camera worker, queuedRequest() calls may have queued
asynchronous function invocation messages to the worker thread, and some
of those messages may not have been processed yet. The messages will
stay in the thread's queue until the camera worker is restarted (when
the camera service will start a new capture session). At that point,
they will be dispatched, which will cause a crash due to the
CaptureRequest passed to processRequest() having been deleted by
CameraDevice::stop() calling descriptors_.clear().

Fix this by forcing dispatching of all function invocation messages when
stopping the camera worker thread. Note that this is inherently racy, as
more queueRequest() calls may arrive from the camera service while we're
stopping. This race condition will be addressed by a subsequent patch
series.

Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
I haven't tested this patch, as I'm currently rebuilding a new Soraka
image. Hiro, could you give it a try to see if it fixes the problem
you've reported ?
---
 src/android/camera_worker.cpp | 14 ++++++++++----
 src/android/camera_worker.h   |  6 ++++--
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/src/android/camera_worker.cpp b/src/android/camera_worker.cpp
index 300ddde03645..9f727826e23f 100644
--- a/src/android/camera_worker.cpp
+++ b/src/android/camera_worker.cpp
@@ -52,18 +52,24 @@ void CaptureRequest::queue()
  */
 CameraWorker::CameraWorker()
 {
-	worker_.moveToThread(&thread_);
+	worker_.moveToThread(this);
 }
 
 void CameraWorker::start()
 {
-	thread_.start();
+	Thread::start();
 }
 
 void CameraWorker::stop()
 {
-	thread_.exit();
-	thread_.wait();
+	exit();
+	wait();
+}
+
+void CameraWorker::run()
+{
+	exec();
+	dispatchMessages(Message::Type::InvokeMessage);
 }
 
 void CameraWorker::queueRequest(CaptureRequest *request)
diff --git a/src/android/camera_worker.h b/src/android/camera_worker.h
index 64b1658b61b4..e289ef9b8655 100644
--- a/src/android/camera_worker.h
+++ b/src/android/camera_worker.h
@@ -42,7 +42,7 @@ private:
 	std::unique_ptr<libcamera::Request> request_;
 };
 
-class CameraWorker
+class CameraWorker : private libcamera::Thread
 {
 public:
 	CameraWorker();
@@ -52,6 +52,9 @@ public:
 
 	void queueRequest(CaptureRequest *request);
 
+protected:
+	void run() override;
+
 private:
 	class Worker : public libcamera::Object
 	{
@@ -63,7 +66,6 @@ private:
 	};
 
 	Worker worker_;
-	libcamera::Thread thread_;
 };
 
 #endif /* __ANDROID_CAMERA_WORKER_H__ */
-- 
Regards,

Laurent Pinchart



More information about the libcamera-devel mailing list