[libcamera-devel] [PATCH v2 3/3] libcamera: camera: Ensure deletion via deleteLater()

Umang Jain email at uajain.com
Fri Jul 31 12:53:43 CEST 2020


Object::deleteLater() ensures that the deletion of the Object
takes place in a thread it is bound to. Deleting the Object
in a different thread is a violation according to the threading
model.

On hot-unplug of a currently streaming camera, the last reference
of Camera when dropped from the application thread (for e.g. QCam's
thread), the destructor is then called from this thread. This is not
allowed by the threading model. Camera is meant to be deleted in the
thread it is bound to - in this case the CameraManager's thread.

Signed-off-by: Umang Jain <email at uajain.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 include/libcamera/camera.h       | 3 ++-
 src/libcamera/camera.cpp         | 2 +-
 src/libcamera/camera_manager.cpp | 6 +++++-
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h
index 4d1a4a9..7dd23d7 100644
--- a/include/libcamera/camera.h
+++ b/include/libcamera/camera.h
@@ -13,6 +13,7 @@
 #include <string>
 
 #include <libcamera/controls.h>
+#include <libcamera/object.h>
 #include <libcamera/request.h>
 #include <libcamera/signal.h>
 #include <libcamera/stream.h>
@@ -66,7 +67,7 @@ protected:
 	std::vector<StreamConfiguration> config_;
 };
 
-class Camera final : public std::enable_shared_from_this<Camera>
+class Camera final : public Object, public std::enable_shared_from_this<Camera>
 {
 public:
 	static std::shared_ptr<Camera> create(PipelineHandler *pipe,
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index 69a1b44..034f341 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -464,7 +464,7 @@ std::shared_ptr<Camera> Camera::create(PipelineHandler *pipe,
 	struct Deleter : std::default_delete<Camera> {
 		void operator()(Camera *camera)
 		{
-			delete camera;
+			camera->deleteLater();
 		}
 	};
 
diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp
index f60491d..c45bf33 100644
--- a/src/libcamera/camera_manager.cpp
+++ b/src/libcamera/camera_manager.cpp
@@ -164,9 +164,13 @@ void CameraManager::Private::cleanup()
 
 	/*
 	 * Release all references to cameras to ensure they all get destroyed
-	 * before the device enumerator deletes the media devices.
+	 * before the device enumerator deletes the media devices. Cameras are
+	 * destroyed via Object::deleteLater() API, hence we need to explicitly
+	 * process deletion requests from the thread's message queue as the event
+	 * loop is not in action here.
 	 */
 	cameras_.clear();
+	dispatchMessages(Message::Type::DeferredDelete);
 
 	enumerator_.reset(nullptr);
 }
-- 
2.26.2



More information about the libcamera-devel mailing list