diff options
Diffstat (limited to 'src/libcamera/pipeline_handler.cpp')
-rw-r--r-- | src/libcamera/pipeline_handler.cpp | 18 |
1 files changed, 15 insertions, 3 deletions
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(); } /** |