diff options
-rw-r--r-- | src/libcamera/camera_manager.cpp | 8 | ||||
-rw-r--r-- | src/libcamera/pipeline_handler.cpp | 18 |
2 files changed, 17 insertions, 9 deletions
diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp index 576856ab..dbdc78e7 100644 --- a/src/libcamera/camera_manager.cpp +++ b/src/libcamera/camera_manager.cpp @@ -63,7 +63,6 @@ private: bool initialized_; int status_; - std::vector<std::shared_ptr<PipelineHandler>> pipes_; std::unique_ptr<DeviceEnumerator> enumerator_; IPAManager ipaManager_; @@ -144,7 +143,6 @@ int CameraManager::Private::init() LOG(Camera, Debug) << "Pipeline handler \"" << factory->name() << "\" matched"; - pipes_.push_back(std::move(pipe)); } } @@ -158,11 +156,9 @@ void CameraManager::Private::cleanup() /* TODO: unregister hot-plug callback here */ /* - * Release all references to cameras and pipeline handlers to ensure - * they all get destroyed before the device enumerator deletes the - * media devices. + * Release all references to cameras to ensure they all get destroyed + * before the device enumerator deletes the media devices. */ - pipes_.clear(); cameras_.clear(); enumerator_.reset(nullptr); diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index a0f6b0f1..38c85779 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -559,7 +559,21 @@ void PipelineHandler::mediaDeviceDisconnected(MediaDevice *media) */ void PipelineHandler::disconnect() { - for (std::weak_ptr<Camera> ptr : cameras_) { + /* + * Each camera holds a reference to its associated pipeline handler + * instance. Hence, when the last camera is dropped, the pipeline + * handler will get destroyed by the last manager_->removeCamera(camera) + * call in the loop below. + * + * This is acceptable as long as we make sure that the code path does not + * access any member of the (already destroyed) pipeline handler instance + * afterwards. Therefore, we move the cameras_ vector to a local temporary + * container to avoid accessing freed memory later i.e. to explicitly run + * cameras_.clear(). + */ + std::vector<std::weak_ptr<Camera>> cameras{ std::move(cameras_) }; + + for (std::weak_ptr<Camera> ptr : cameras) { std::shared_ptr<Camera> camera = ptr.lock(); if (!camera) continue; @@ -567,8 +581,6 @@ void PipelineHandler::disconnect() camera->disconnect(); manager_->removeCamera(camera.get()); } - - cameras_.clear(); } /** |