diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libcamera/message.cpp | 2 | ||||
-rw-r--r-- | src/libcamera/object.cpp | 48 |
2 files changed, 50 insertions, 0 deletions
diff --git a/src/libcamera/message.cpp b/src/libcamera/message.cpp index e9b3e73f..bc985c07 100644 --- a/src/libcamera/message.cpp +++ b/src/libcamera/message.cpp @@ -49,6 +49,8 @@ std::atomic_uint Message::nextUserType_{ Message::UserMessage }; * \brief Asynchronous method invocation across threads * \var Message::ThreadMoveMessage * \brief Object is being moved to a different thread + * \var Message::DeferredDelete + * \brief Object is scheduled for deletion * \var Message::UserMessage * \brief First value available for user-defined messages */ diff --git a/src/libcamera/object.cpp b/src/libcamera/object.cpp index 1544a23e..647ccda7 100644 --- a/src/libcamera/object.cpp +++ b/src/libcamera/object.cpp @@ -73,6 +73,10 @@ Object::Object(Object *parent) * Deleting an Object automatically disconnects all signals from the Object's * slots. All the Object's children are made orphan, but stay bound to their * current thread. + * + * Object instances shall be destroyed from the thread they are bound to, + * otherwise undefined behaviour may occur. If deletion of an Object needs to + * be scheduled from a different thread, deleteLater() shall be used. */ Object::~Object() { @@ -99,6 +103,46 @@ Object::~Object() } /** + * \brief Schedule deletion of the instance in the thread it belongs to + * + * This function schedules deletion of the Object when control returns to the + * event loop that the object belongs to. This ensures the object is destroyed + * from the right context, as required by the libcamera threading model. + * + * If this function is called before the thread's event loop is started, the + * object will be deleted when the event loop starts. + * + * Deferred deletion can be used to control the destruction context with shared + * pointers. An object managed with shared pointers is deleted when the last + * reference is destroyed, which makes difficult to ensure through software + * design which context the deletion will take place in. With a custom deleter + * for the shared pointer using deleteLater(), the deletion can be guaranteed to + * happen in the thread the object is bound to. + * + * \code{.cpp} + * std::shared_ptr<MyObject> createObject() + * { + * struct Deleter : std::default_delete<MyObject> { + * void operator()(MyObject *obj) + * { + * delete obj; + * } + * }; + * + * MyObject *obj = new MyObject(); + * + * return std::shared_ptr<MyObject>(obj, Deleter()); + * } + * \endcode + * + * \context This function is \threadsafe. + */ +void Object::deleteLater() +{ + postMessage(std::make_unique<Message>(Message::DeferredDelete)); +} + +/** * \brief Post a message to the object's thread * \param[in] msg The message * @@ -144,6 +188,10 @@ void Object::message(Message *msg) break; } + case Message::DeferredDelete: + delete this; + break; + default: break; } |