[{"id":19083,"web_url":"https://patchwork.libcamera.org/comment/19083/","msgid":"<YSbPsNPh7tbLsxda@pendragon.ideasonboard.com>","date":"2021-08-25T23:18:08","subject":"Re: [libcamera-devel] [PATCH v1 2/3] gstreamer: Fix concurrent\n\taccess issues to CameraManager","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Nicolas,\n\nThank you for the patch.\n\nOn Wed, Aug 25, 2021 at 05:18:51PM -0400, Nicolas Dufresne wrote:\n> From: Nicolas Dufresne <nicolas.dufresne@collabora.com>\n> \n> It's not allowed to have multiple instances of CameraManager. This\n> requirement is not easy for GStreamer were the device monitor and\n> the camerasrc, or two camerasrc instances don't usually have any\n> interaction between each other. This this by implementing a minimalist\n\ns/This this/Fix this/ ?\n\n> singleton around CameraManager constructor and start()/stop()\n> operations.\n> \n> Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>\n> ---\n>  src/gstreamer/gstlibcamera-utils.cpp   | 31 ++++++++++++++++++++++++++\n>  src/gstreamer/gstlibcamera-utils.h     |  6 +++--\n>  src/gstreamer/gstlibcameraprovider.cpp | 22 ++----------------\n>  src/gstreamer/gstlibcamerasrc.cpp      | 11 +++++----\n>  4 files changed, 42 insertions(+), 28 deletions(-)\n> \n> diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp\n> index 007d6a64..34b64c4a 100644\n> --- a/src/gstreamer/gstlibcamera-utils.cpp\n> +++ b/src/gstreamer/gstlibcamera-utils.cpp\n> @@ -221,3 +221,34 @@ gst_libcamera_resume_task(GstTask *task)\n>  \t\tGST_TASK_SIGNAL(task);\n>  \t}\n>  }\n> +\n> +G_LOCK_DEFINE_STATIC(cm_singleton_lock);\n> +std::weak_ptr<CameraManager> cm_singleton_ptr;\n> +\n> +void _cm_deleter(CameraManager *cm)\n> +{\n> +\tg_print(\"Delete CameraManager\\n\");\n> +\tcm->stop();\n> +\tdelete cm;\n\nThe CameraManager destructor calls stop(), so if you don't care much\nabout the g_print(), you could drop this function.\n\n> +}\n> +\n> +std::shared_ptr<CameraManager>\n> +gst_libcamera_get_camera_mananger(int &ret)\n> +{\n> +\tstd::shared_ptr<CameraManager> cm;\n> +\n> +\tG_LOCK(cm_singleton_lock);\n> +\n> +\tcm = cm_singleton_ptr.lock();\n> +\tif (cm_singleton_ptr.expired()) {\n\nI think you could write this\n\n\tcm = cm_singleton_ptr.lock();\n\tif (cm) {\n\nas std::weak_ptr<>::lock() return a null std::shared_ptr<> if it has\nexpired.\n\n> +\t\tstd::shared_ptr<CameraManager> ptr(new CameraManager(), _cm_deleter);\n> +\t\tcm_singleton_ptr = cm = ptr;\n\nAnd there's no need for the local ptr variable here, you can write\n\n\t\tcm = std::shared_ptr<CameraManager>(new CameraManager(), _cm_deleter);\n\t\tcm_singleton_ptr = cm;\n\nIf you don't care about the deleter, it could also become\n\n\t\tcm = std::make_shared<CameraManager>();\n\t\tcm_singleton_ptr = cm;\n\n> +\t\tret = cm->start();\n> +\t} else {\n> +\t\tret = 0;\n> +\t}\n> +\n> +\tG_UNLOCK(cm_singleton_lock);\n> +\n> +\treturn cm;\n> +}\n> diff --git a/src/gstreamer/gstlibcamera-utils.h b/src/gstreamer/gstlibcamera-utils.h\n> index 2b3f26b6..67a06db3 100644\n> --- a/src/gstreamer/gstlibcamera-utils.h\n> +++ b/src/gstreamer/gstlibcamera-utils.h\n> @@ -9,16 +9,18 @@\n>  #ifndef __GST_LIBCAMERA_UTILS_H__\n>  #define __GST_LIBCAMERA_UTILS_H__\n>  \n> +#include <libcamera/camera_manager.h>\n> +#include <libcamera/stream.h>\n> +\n>  #include <gst/gst.h>\n>  #include <gst/video/video.h>\n>  \n> -#include <libcamera/stream.h>\n> -\n>  GstCaps *gst_libcamera_stream_formats_to_caps(const libcamera::StreamFormats &formats);\n>  GstCaps *gst_libcamera_stream_configuration_to_caps(const libcamera::StreamConfiguration &stream_cfg);\n>  void gst_libcamera_configure_stream_from_caps(libcamera::StreamConfiguration &stream_cfg,\n>  \t\t\t\t\t      GstCaps *caps);\n>  void gst_libcamera_resume_task(GstTask *task);\n> +std::shared_ptr<libcamera::CameraManager> gst_libcamera_get_camera_mananger(int &ret);\n>  \n>  /**\n>   * \\class GLibLocker\n> diff --git a/src/gstreamer/gstlibcameraprovider.cpp b/src/gstreamer/gstlibcameraprovider.cpp\n> index 29da6c32..948ba0d1 100644\n> --- a/src/gstreamer/gstlibcameraprovider.cpp\n> +++ b/src/gstreamer/gstlibcameraprovider.cpp\n> @@ -158,7 +158,6 @@ gst_libcamera_device_new(const std::shared_ptr<Camera> &camera)\n>  \n>  struct _GstLibcameraProvider {\n>  \tGstDeviceProvider parent;\n> -\tCameraManager *cm;\n>  };\n\nIs this constructed on demand to call probe() and then immediately\ndestroyed that it makes no sense anymore to cache the pointer ?\n\n>  \n>  G_DEFINE_TYPE_WITH_CODE(GstLibcameraProvider, gst_libcamera_provider,\n> @@ -170,7 +169,7 @@ static GList *\n>  gst_libcamera_provider_probe(GstDeviceProvider *provider)\n>  {\n>  \tGstLibcameraProvider *self = GST_LIBCAMERA_PROVIDER(provider);\n> -\tCameraManager *cm = self->cm;\n> +\tstd::shared_ptr<CameraManager> cm;\n>  \tGList *devices = nullptr;\n>  \tgint ret;\n>  \n> @@ -181,7 +180,7 @@ gst_libcamera_provider_probe(GstDeviceProvider *provider)\n>  \t * gains monitoring support. Meanwhile we need to cycle start()/stop()\n>  \t * to ensure every probe() calls return the latest list.\n>  \t */\n> -\tret = cm->start();\n> +\tcm = gst_libcamera_get_camera_mananger(ret);\n>  \tif (ret) {\n>  \t\tGST_ERROR_OBJECT(self, \"Failed to retrieve device list: %s\",\n>  \t\t\t\t g_strerror(-ret));\n> @@ -194,8 +193,6 @@ gst_libcamera_provider_probe(GstDeviceProvider *provider)\n>  \t\t\t\t\tg_object_ref_sink(gst_libcamera_device_new(camera)));\n>  \t}\n>  \n> -\tcm->stop();\n> -\n>  \treturn devices;\n>  }\n>  \n> @@ -204,31 +201,16 @@ gst_libcamera_provider_init(GstLibcameraProvider *self)\n>  {\n>  \tGstDeviceProvider *provider = GST_DEVICE_PROVIDER(self);\n>  \n> -\tself->cm = new CameraManager();\n> -\n>  \t/* Avoid devices being duplicated. */\n>  \tgst_device_provider_hide_provider(provider, \"v4l2deviceprovider\");\n>  }\n>  \n> -static void\n> -gst_libcamera_provider_finalize(GObject *object)\n> -{\n> -\tGstLibcameraProvider *self = GST_LIBCAMERA_PROVIDER(object);\n> -\tgpointer klass = gst_libcamera_provider_parent_class;\n> -\n> -\tdelete self->cm;\n> -\n> -\treturn G_OBJECT_CLASS(klass)->finalize(object);\n> -}\n> -\n>  static void\n>  gst_libcamera_provider_class_init(GstLibcameraProviderClass *klass)\n>  {\n>  \tGstDeviceProviderClass *provider_class = GST_DEVICE_PROVIDER_CLASS(klass);\n> -\tGObjectClass *object_class = G_OBJECT_CLASS(klass);\n>  \n>  \tprovider_class->probe = gst_libcamera_provider_probe;\n> -\tobject_class->finalize = gst_libcamera_provider_finalize;\n>  \n>  \tgst_device_provider_class_set_metadata(provider_class,\n>  \t\t\t\t\t       \"libcamera Device Provider\",\n> diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp\n> index 4c7b36ae..bdd9f88c 100644\n> --- a/src/gstreamer/gstlibcamerasrc.cpp\n> +++ b/src/gstreamer/gstlibcamerasrc.cpp\n> @@ -104,7 +104,7 @@ GstBuffer *RequestWrap::detachBuffer(Stream *stream)\n>  struct GstLibcameraSrcState {\n>  \tGstLibcameraSrc *src_;\n>  \n> -\tstd::unique_ptr<CameraManager> cm_;\n> +\tstd::shared_ptr<CameraManager> cm_;\n>  \tstd::shared_ptr<Camera> cam_;\n>  \tstd::unique_ptr<CameraConfiguration> config_;\n>  \tstd::vector<GstPad *> srcpads_;\n> @@ -198,13 +198,13 @@ GstLibcameraSrcState::requestCompleted(Request *request)\n>  static bool\n>  gst_libcamera_src_open(GstLibcameraSrc *self)\n>  {\n> -\tstd::unique_ptr<CameraManager> cm = std::make_unique<CameraManager>();\n> +\tstd::shared_ptr<CameraManager> cm;\n>  \tstd::shared_ptr<Camera> cam;\n> -\tgint ret = 0;\n> +\tgint ret;\n>  \n>  \tGST_DEBUG_OBJECT(self, \"Opening camera device ...\");\n>  \n> -\tret = cm->start();\n> +\tcm = gst_libcamera_get_camera_mananger(ret);\n>  \tif (ret) {\n>  \t\tGST_ELEMENT_ERROR(self, LIBRARY, INIT,\n>  \t\t\t\t  (\"Failed listing cameras.\"),\n> @@ -250,7 +250,7 @@ gst_libcamera_src_open(GstLibcameraSrc *self)\n>  \tcam->requestCompleted.connect(self->state, &GstLibcameraSrcState::requestCompleted);\n>  \n>  \t/* No need to lock here, we didn't start our threads yet. */\n> -\tself->state->cm_ = std::move(cm);\n> +\tself->state->cm_ = cm;\n>  \tself->state->cam_ = cam;\n>  \n>  \treturn true;\n> @@ -517,7 +517,6 @@ gst_libcamera_src_close(GstLibcameraSrc *self)\n>  \t}\n>  \n>  \tstate->cam_.reset();\n> -\tstate->cm_->stop();\n>  \tstate->cm_.reset();\n>  }\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id B6EE9BD87C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 25 Aug 2021 23:18:22 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id EB45D68891;\n\tThu, 26 Aug 2021 01:18:21 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 8742260504\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 26 Aug 2021 01:18:20 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id EF2C424F;\n\tThu, 26 Aug 2021 01:18:19 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"fxGa19+Q\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1629933500;\n\tbh=2UPZysjxs/iJz6oKpPFh0sv/+4KBMhowG0THpHi8u8s=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=fxGa19+QSwsthgxnFLRTlWcA6DHLQS0/CXc1sRwOzehzMj8LWBqcRcdELwn+6/DbD\n\tRVGDEuBEDvB09scLiCrDTm7R8AkEH+31Wrh8wK7WpY5GsJPVZ0O/76nLb43GLh4imf\n\t0Sz+747KIKwOBQs3SA+/ptjhoU9zyxiwVTZKKGgU=","Date":"Thu, 26 Aug 2021 02:18:08 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Nicolas Dufresne <nicolas@ndufresne.ca>","Message-ID":"<YSbPsNPh7tbLsxda@pendragon.ideasonboard.com>","References":"<20210825211852.1207168-1-nicolas@ndufresne.ca>\n\t<20210825211852.1207168-3-nicolas@ndufresne.ca>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20210825211852.1207168-3-nicolas@ndufresne.ca>","Subject":"Re: [libcamera-devel] [PATCH v1 2/3] gstreamer: Fix concurrent\n\taccess issues to CameraManager","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org,\n\tNicolas Dufresne <nicolas.dufresne@collabora.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":19098,"web_url":"https://patchwork.libcamera.org/comment/19098/","msgid":"<6995c35bda65ff1dcfac3f0477a17cc0fda478db.camel@collabora.com>","date":"2021-08-26T13:21:00","subject":"Re: [libcamera-devel] [PATCH v1 2/3] gstreamer: Fix concurrent\n\taccess issues to CameraManager","submitter":{"id":31,"url":"https://patchwork.libcamera.org/api/people/31/","name":"Nicolas Dufresne","email":"nicolas.dufresne@collabora.com"},"content":"Le jeudi 26 août 2021 à 02:18 +0300, Laurent Pinchart a écrit :\n> Hi Nicolas,\n> \n> Thank you for the patch.\n> \n> On Wed, Aug 25, 2021 at 05:18:51PM -0400, Nicolas Dufresne wrote:\n> > From: Nicolas Dufresne <nicolas.dufresne@collabora.com>\n> > \n> > It's not allowed to have multiple instances of CameraManager. This\n> > requirement is not easy for GStreamer were the device monitor and\n> > the camerasrc, or two camerasrc instances don't usually have any\n> > interaction between each other. This this by implementing a minimalist\n> \n> s/This this/Fix this/ ?\n> \n> > singleton around CameraManager constructor and start()/stop()\n> > operations.\n> > \n> > Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>\n> > ---\n> >  src/gstreamer/gstlibcamera-utils.cpp   | 31 ++++++++++++++++++++++++++\n> >  src/gstreamer/gstlibcamera-utils.h     |  6 +++--\n> >  src/gstreamer/gstlibcameraprovider.cpp | 22 ++----------------\n> >  src/gstreamer/gstlibcamerasrc.cpp      | 11 +++++----\n> >  4 files changed, 42 insertions(+), 28 deletions(-)\n> > \n> > diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp\n> > index 007d6a64..34b64c4a 100644\n> > --- a/src/gstreamer/gstlibcamera-utils.cpp\n> > +++ b/src/gstreamer/gstlibcamera-utils.cpp\n> > @@ -221,3 +221,34 @@ gst_libcamera_resume_task(GstTask *task)\n> >  \t\tGST_TASK_SIGNAL(task);\n> >  \t}\n> >  }\n> > +\n> > +G_LOCK_DEFINE_STATIC(cm_singleton_lock);\n> > +std::weak_ptr<CameraManager> cm_singleton_ptr;\n> > +\n> > +void _cm_deleter(CameraManager *cm)\n> > +{\n> > +\tg_print(\"Delete CameraManager\\n\");\n> > +\tcm->stop();\n> > +\tdelete cm;\n> \n> The CameraManager destructor calls stop(), so if you don't care much\n> about the g_print(), you could drop this function.\n> \n> > +}\n> > +\n> > +std::shared_ptr<CameraManager>\n> > +gst_libcamera_get_camera_mananger(int &ret)\n> > +{\n> > +\tstd::shared_ptr<CameraManager> cm;\n> > +\n> > +\tG_LOCK(cm_singleton_lock);\n> > +\n> > +\tcm = cm_singleton_ptr.lock();\n> > +\tif (cm_singleton_ptr.expired()) {\n> \n> I think you could write this\n> \n> \tcm = cm_singleton_ptr.lock();\n> \tif (cm) {\n\nWith \"if (!cm)\" that works.\n\n> \n> as std::weak_ptr<>::lock() return a null std::shared_ptr<> if it has\n> expired.\n> \n> > +\t\tstd::shared_ptr<CameraManager> ptr(new CameraManager(), _cm_deleter);\n> > +\t\tcm_singleton_ptr = cm = ptr;\n> \n> And there's no need for the local ptr variable here, you can write\n> \n> \t\tcm = std::shared_ptr<CameraManager>(new CameraManager(), _cm_deleter);\n> \t\tcm_singleton_ptr = cm;\n> \n> If you don't care about the deleter, it could also become\n\nI'll drop the deleter if I don't need to call stop() explicitly.\n\n> \n> \t\tcm = std::make_shared<CameraManager>();\n> \t\tcm_singleton_ptr = cm;\n> \n> > +\t\tret = cm->start();\n> > +\t} else {\n> > +\t\tret = 0;\n> > +\t}\n> > +\n> > +\tG_UNLOCK(cm_singleton_lock);\n> > +\n> > +\treturn cm;\n> > +}\n> > diff --git a/src/gstreamer/gstlibcamera-utils.h b/src/gstreamer/gstlibcamera-utils.h\n> > index 2b3f26b6..67a06db3 100644\n> > --- a/src/gstreamer/gstlibcamera-utils.h\n> > +++ b/src/gstreamer/gstlibcamera-utils.h\n> > @@ -9,16 +9,18 @@\n> >  #ifndef __GST_LIBCAMERA_UTILS_H__\n> >  #define __GST_LIBCAMERA_UTILS_H__\n> >  \n> > +#include <libcamera/camera_manager.h>\n> > +#include <libcamera/stream.h>\n> > +\n> >  #include <gst/gst.h>\n> >  #include <gst/video/video.h>\n> >  \n> > -#include <libcamera/stream.h>\n> > -\n> >  GstCaps *gst_libcamera_stream_formats_to_caps(const libcamera::StreamFormats &formats);\n> >  GstCaps *gst_libcamera_stream_configuration_to_caps(const libcamera::StreamConfiguration &stream_cfg);\n> >  void gst_libcamera_configure_stream_from_caps(libcamera::StreamConfiguration &stream_cfg,\n> >  \t\t\t\t\t      GstCaps *caps);\n> >  void gst_libcamera_resume_task(GstTask *task);\n> > +std::shared_ptr<libcamera::CameraManager> gst_libcamera_get_camera_mananger(int &ret);\n> >  \n> >  /**\n> >   * \\class GLibLocker\n> > diff --git a/src/gstreamer/gstlibcameraprovider.cpp b/src/gstreamer/gstlibcameraprovider.cpp\n> > index 29da6c32..948ba0d1 100644\n> > --- a/src/gstreamer/gstlibcameraprovider.cpp\n> > +++ b/src/gstreamer/gstlibcameraprovider.cpp\n> > @@ -158,7 +158,6 @@ gst_libcamera_device_new(const std::shared_ptr<Camera> &camera)\n> >  \n> >  struct _GstLibcameraProvider {\n> >  \tGstDeviceProvider parent;\n> > -\tCameraManager *cm;\n> >  };\n> \n> Is this constructed on demand to call probe() and then immediately\n> destroyed that it makes no sense anymore to cache the pointer ?\n\nCorrect, this is a bit of an intermediate. In this temporary implementation\n(non-monitoring). I was doing start() enum stop(), so that each time probe is\ncalled the list was fresh. This is as close as I can get using a singleton here.\nBut consider this a temporary state.\n\nTo support the new API, we need a C++ class to hold the shared ptr (like\nlibcamersrc). I'll introduce this while adding monitoring support. This is just\nto keep the the thing minimally working and small.\n\n> \n> >  \n> >  G_DEFINE_TYPE_WITH_CODE(GstLibcameraProvider, gst_libcamera_provider,\n> > @@ -170,7 +169,7 @@ static GList *\n> >  gst_libcamera_provider_probe(GstDeviceProvider *provider)\n> >  {\n> >  \tGstLibcameraProvider *self = GST_LIBCAMERA_PROVIDER(provider);\n> > -\tCameraManager *cm = self->cm;\n> > +\tstd::shared_ptr<CameraManager> cm;\n> >  \tGList *devices = nullptr;\n> >  \tgint ret;\n> >  \n> > @@ -181,7 +180,7 @@ gst_libcamera_provider_probe(GstDeviceProvider *provider)\n> >  \t * gains monitoring support. Meanwhile we need to cycle start()/stop()\n> >  \t * to ensure every probe() calls return the latest list.\n> >  \t */\n> > -\tret = cm->start();\n> > +\tcm = gst_libcamera_get_camera_mananger(ret);\n> >  \tif (ret) {\n> >  \t\tGST_ERROR_OBJECT(self, \"Failed to retrieve device list: %s\",\n> >  \t\t\t\t g_strerror(-ret));\n> > @@ -194,8 +193,6 @@ gst_libcamera_provider_probe(GstDeviceProvider *provider)\n> >  \t\t\t\t\tg_object_ref_sink(gst_libcamera_device_new(camera)));\n> >  \t}\n> >  \n> > -\tcm->stop();\n> > -\n> >  \treturn devices;\n> >  }\n> >  \n> > @@ -204,31 +201,16 @@ gst_libcamera_provider_init(GstLibcameraProvider *self)\n> >  {\n> >  \tGstDeviceProvider *provider = GST_DEVICE_PROVIDER(self);\n> >  \n> > -\tself->cm = new CameraManager();\n> > -\n> >  \t/* Avoid devices being duplicated. */\n> >  \tgst_device_provider_hide_provider(provider, \"v4l2deviceprovider\");\n> >  }\n> >  \n> > -static void\n> > -gst_libcamera_provider_finalize(GObject *object)\n> > -{\n> > -\tGstLibcameraProvider *self = GST_LIBCAMERA_PROVIDER(object);\n> > -\tgpointer klass = gst_libcamera_provider_parent_class;\n> > -\n> > -\tdelete self->cm;\n> > -\n> > -\treturn G_OBJECT_CLASS(klass)->finalize(object);\n> > -}\n> > -\n> >  static void\n> >  gst_libcamera_provider_class_init(GstLibcameraProviderClass *klass)\n> >  {\n> >  \tGstDeviceProviderClass *provider_class = GST_DEVICE_PROVIDER_CLASS(klass);\n> > -\tGObjectClass *object_class = G_OBJECT_CLASS(klass);\n> >  \n> >  \tprovider_class->probe = gst_libcamera_provider_probe;\n> > -\tobject_class->finalize = gst_libcamera_provider_finalize;\n> >  \n> >  \tgst_device_provider_class_set_metadata(provider_class,\n> >  \t\t\t\t\t       \"libcamera Device Provider\",\n> > diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp\n> > index 4c7b36ae..bdd9f88c 100644\n> > --- a/src/gstreamer/gstlibcamerasrc.cpp\n> > +++ b/src/gstreamer/gstlibcamerasrc.cpp\n> > @@ -104,7 +104,7 @@ GstBuffer *RequestWrap::detachBuffer(Stream *stream)\n> >  struct GstLibcameraSrcState {\n> >  \tGstLibcameraSrc *src_;\n> >  \n> > -\tstd::unique_ptr<CameraManager> cm_;\n> > +\tstd::shared_ptr<CameraManager> cm_;\n> >  \tstd::shared_ptr<Camera> cam_;\n> >  \tstd::unique_ptr<CameraConfiguration> config_;\n> >  \tstd::vector<GstPad *> srcpads_;\n> > @@ -198,13 +198,13 @@ GstLibcameraSrcState::requestCompleted(Request *request)\n> >  static bool\n> >  gst_libcamera_src_open(GstLibcameraSrc *self)\n> >  {\n> > -\tstd::unique_ptr<CameraManager> cm = std::make_unique<CameraManager>();\n> > +\tstd::shared_ptr<CameraManager> cm;\n> >  \tstd::shared_ptr<Camera> cam;\n> > -\tgint ret = 0;\n> > +\tgint ret;\n> >  \n> >  \tGST_DEBUG_OBJECT(self, \"Opening camera device ...\");\n> >  \n> > -\tret = cm->start();\n> > +\tcm = gst_libcamera_get_camera_mananger(ret);\n> >  \tif (ret) {\n> >  \t\tGST_ELEMENT_ERROR(self, LIBRARY, INIT,\n> >  \t\t\t\t  (\"Failed listing cameras.\"),\n> > @@ -250,7 +250,7 @@ gst_libcamera_src_open(GstLibcameraSrc *self)\n> >  \tcam->requestCompleted.connect(self->state, &GstLibcameraSrcState::requestCompleted);\n> >  \n> >  \t/* No need to lock here, we didn't start our threads yet. */\n> > -\tself->state->cm_ = std::move(cm);\n> > +\tself->state->cm_ = cm;\n> >  \tself->state->cam_ = cam;\n> >  \n> >  \treturn true;\n> > @@ -517,7 +517,6 @@ gst_libcamera_src_close(GstLibcameraSrc *self)\n> >  \t}\n> >  \n> >  \tstate->cam_.reset();\n> > -\tstate->cm_->stop();\n> >  \tstate->cm_.reset();\n> >  }\n> >  \n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 47405BD87C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 26 Aug 2021 13:21:16 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id AE22368920;\n\tThu, 26 Aug 2021 15:21:15 +0200 (CEST)","from bhuna.collabora.co.uk (bhuna.collabora.co.uk [46.235.227.227])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 595436888F\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 26 Aug 2021 15:21:14 +0200 (CEST)","from [127.0.0.1] (localhost [127.0.0.1])\n\t(Authenticated sender: nicolas) with ESMTPSA id 7316D1F44328"],"Message-ID":"<6995c35bda65ff1dcfac3f0477a17cc0fda478db.camel@collabora.com>","From":"Nicolas Dufresne <nicolas.dufresne@collabora.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Date":"Thu, 26 Aug 2021 09:21:00 -0400","In-Reply-To":"<YSbPsNPh7tbLsxda@pendragon.ideasonboard.com>","References":"<20210825211852.1207168-1-nicolas@ndufresne.ca>\n\t<20210825211852.1207168-3-nicolas@ndufresne.ca>\n\t<YSbPsNPh7tbLsxda@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=\"UTF-8\"","User-Agent":"Evolution 3.40.4 (3.40.4-1.fc34) ","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","Subject":"Re: [libcamera-devel] [PATCH v1 2/3] gstreamer: Fix concurrent\n\taccess issues to CameraManager","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]