From 98bd9cb8c9f370c977dc3b6cc14f3d1ebfd24563 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 8 Feb 2019 00:24:14 +0200 Subject: libcamera: signal: Disconnect signal automatically on slot deletion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a signal is connected to a member function slot, the slot is not disconnected when the slot object is deleted. This can lead to calling a member function of a deleted object if the signal isn't disconnected manually by the slot object's destructor. Make signal handling easier by implementing a base Object class that tracks all connected signals and disconnects from them automatically when the object is deleted, using template specialization resolution in the Signal class. As inheriting from the Object class may to a too harsh requirement for Signal usage in applications, keep the existing behaviour working if the slot doesn't inherit from the Object class. We may reconsider this later and require all slot objects to inherit from the Object class. Signed-off-by: Laurent Pinchart Reviewed-by: Niklas Söderlund --- src/libcamera/meson.build | 1 + src/libcamera/object.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++++++ src/libcamera/signal.cpp | 5 +++++ 3 files changed, 56 insertions(+) create mode 100644 src/libcamera/object.cpp (limited to 'src') diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index c5354c13..8384cd0a 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -10,6 +10,7 @@ libcamera_sources = files([ 'log.cpp', 'media_device.cpp', 'media_object.cpp', + 'object.cpp', 'pipeline_handler.cpp', 'request.cpp', 'signal.cpp', diff --git a/src/libcamera/object.cpp b/src/libcamera/object.cpp new file mode 100644 index 00000000..826eed6f --- /dev/null +++ b/src/libcamera/object.cpp @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * object.cpp - Base object + */ + +#include +#include + +/** + * \file object.h + * \brief Base object to support automatic signal disconnection + */ + +namespace libcamera { + +/** + * \class Object + * \brief Base object to support automatic signal disconnection + * + * The Object class simplifies signal/slot handling for classes implementing + * slots. By inheriting from Object, an object is automatically disconnected + * from all connected signals when it gets destroyed. + * + * \sa Signal + */ + +Object::~Object() +{ + for (SignalBase *signal : signals_) + signal->disconnect(this); +} + +void Object::connect(SignalBase *signal) +{ + signals_.push_back(signal); +} + +void Object::disconnect(SignalBase *signal) +{ + for (auto iter = signals_.begin(); iter != signals_.end(); ) { + if (*iter == signal) + iter = signals_.erase(iter); + else + iter++; + } +} + +}; /* namespace libcamera */ diff --git a/src/libcamera/signal.cpp b/src/libcamera/signal.cpp index 8d62b5be..cb7daa11 100644 --- a/src/libcamera/signal.cpp +++ b/src/libcamera/signal.cpp @@ -47,6 +47,11 @@ namespace libcamera { * \brief Connect the signal to a member function slot * \param object The slot object pointer * \param func The slot member function + * + * If the typename T inherits from Object, the signal will be automatically + * disconnected from the \a func slot of \a object when \a object is destroyed. + * Otherwise the caller shall disconnect signals manually before destroying \a + * object. */ /** -- cgit v1.2.1