diff --git a/Documentation/Doxyfile.in b/Documentation/Doxyfile.in index 9e5efae33..5ae8773bd 100644 --- a/Documentation/Doxyfile.in +++ b/Documentation/Doxyfile.in @@ -874,6 +874,7 @@ EXCLUDE_SYMBOLS = libcamera::BoundMemberMethod \ libcamera::BoundMethodArgs \ libcamera::BoundMethodBase \ libcamera::BoundMethodPack \ + libcamera::BoundMethodPackBase \ libcamera::BoundStaticMethod \ libcamera::SignalBase \ std::* diff --git a/include/libcamera/bound_method.h b/include/libcamera/bound_method.h index b50072ffc..a74d2c503 100644 --- a/include/libcamera/bound_method.h +++ b/include/libcamera/bound_method.h @@ -7,6 +7,7 @@ #ifndef __LIBCAMERA_BOUND_METHOD_H__ #define __LIBCAMERA_BOUND_METHOD_H__ +#include #include #include @@ -21,6 +22,24 @@ enum ConnectionType { ConnectionTypeBlocking, }; +class BoundMethodPackBase +{ +public: + virtual ~BoundMethodPackBase() {} +}; + +template +class BoundMethodPack : public BoundMethodPackBase +{ +public: + BoundMethodPack(const Args &... args) + : args_(args...) + { + } + + std::tuple::type...> args_; +}; + class BoundMethodBase { public: @@ -36,7 +55,7 @@ public: Object *object() const { return object_; } - virtual void invokePack(void *pack) = 0; + virtual void invokePack(BoundMethodPackBase *pack) = 0; protected: #ifndef __DOXYGEN__ @@ -58,7 +77,8 @@ protected: }; #endif - void activatePack(void *pack, bool deleteMethod); + void activatePack(std::shared_ptr pack, + bool deleteMethod); void *obj_; Object *object_; @@ -67,18 +87,6 @@ private: ConnectionType connectionType_; }; -template -class BoundMethodPack -{ -public: - BoundMethodPack(const Args &... args) - : args_(args...) - { - } - - std::tuple::type...> args_; -}; - template class BoundMethodArgs : public BoundMethodBase { @@ -87,18 +95,18 @@ public: private: template - void invokePack(void *pack, BoundMethodBase::sequence) + void invokePack(BoundMethodPackBase *pack, BoundMethodBase::sequence) { - PackType *args = static_cast(pack); + /* args is effectively unused when the sequence S is empty. */ + PackType *args [[gnu::unused]] = static_cast(pack); invoke(std::get(args->args_)...); - delete args; } public: BoundMethodArgs(void *obj, Object *object, ConnectionType type) : BoundMethodBase(obj, object, type) {} - void invokePack(void *pack) override + void invokePack(BoundMethodPackBase *pack) override { invokePack(pack, typename BoundMethodBase::generator::type()); } @@ -123,10 +131,14 @@ public: void activate(Args... args, bool deleteMethod = false) override { - if (this->object_) - BoundMethodBase::activatePack(new PackType{ args... }, deleteMethod); - else + if (!this->object_) { (static_cast(this->obj_)->*func_)(args...); + return; + } + + std::shared_ptr pack = + std::make_shared::PackType>(args...); + BoundMethodBase::activatePack(pack, deleteMethod); } void invoke(Args... args) override diff --git a/src/libcamera/bound_method.cpp b/src/libcamera/bound_method.cpp index 45c765774..82339b7e9 100644 --- a/src/libcamera/bound_method.cpp +++ b/src/libcamera/bound_method.cpp @@ -48,7 +48,8 @@ namespace libcamera { * deadlock will occur. */ -void BoundMethodBase::activatePack(void *pack, bool deleteMethod) +void BoundMethodBase::activatePack(std::shared_ptr pack, + bool deleteMethod) { ConnectionType type = connectionType_; if (type == ConnectionTypeAuto) { @@ -61,7 +62,7 @@ void BoundMethodBase::activatePack(void *pack, bool deleteMethod) switch (type) { case ConnectionTypeDirect: default: - invokePack(pack); + invokePack(pack.get()); if (deleteMethod) delete this; break; diff --git a/src/libcamera/include/message.h b/src/libcamera/include/message.h index 311755cc6..8e8b013dc 100644 --- a/src/libcamera/include/message.h +++ b/src/libcamera/include/message.h @@ -48,7 +48,8 @@ private: class InvokeMessage : public Message { public: - InvokeMessage(BoundMethodBase *method, void *pack, + InvokeMessage(BoundMethodBase *method, + std::shared_ptr pack, Semaphore *semaphore = nullptr, bool deleteMethod = false); ~InvokeMessage(); @@ -59,7 +60,7 @@ public: private: BoundMethodBase *method_; - void *pack_; + std::shared_ptr pack_; Semaphore *semaphore_; bool deleteMethod_; }; diff --git a/src/libcamera/message.cpp b/src/libcamera/message.cpp index c35bb33df..77f2bdd5f 100644 --- a/src/libcamera/message.cpp +++ b/src/libcamera/message.cpp @@ -123,7 +123,8 @@ Message::Type Message::registerMessageType() * \param[in] deleteMethod True to delete the \a method when the message is * destroyed */ -InvokeMessage::InvokeMessage(BoundMethodBase *method, void *pack, +InvokeMessage::InvokeMessage(BoundMethodBase *method, + std::shared_ptr pack, Semaphore *semaphore, bool deleteMethod) : Message(Message::InvokeMessage), method_(method), pack_(pack), semaphore_(semaphore), deleteMethod_(deleteMethod) @@ -148,7 +149,7 @@ InvokeMessage::~InvokeMessage() */ void InvokeMessage::invoke() { - method_->invokePack(pack_); + method_->invokePack(pack_.get()); } /**