From: Daniel Elstner Date: Sun, 11 Oct 2015 15:01:05 +0000 (+0200) Subject: C++: Use shared_from_this() exclusively on this X-Git-Tag: libsigrok-0.4.0~171 X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=67b82fc9c9b66baacc9f12b7e65a1e4ff0065618;p=libsigrok.git C++: Use shared_from_this() exclusively on this Never call shared_from_this() on any object other than "this". Adapt the API so that it can be made protected. --- diff --git a/bindings/cxx/classes.cpp b/bindings/cxx/classes.cpp index 960ac39b..2bd25534 100644 --- a/bindings/cxx/classes.cpp +++ b/bindings/cxx/classes.cpp @@ -159,7 +159,7 @@ map> Context::drivers() { auto name = entry.first; auto driver = entry.second; - result[name] = driver->get_shared_pointer(this); + result[name] = driver->get_shared_pointer(shared_from_this()); } return result; } @@ -171,7 +171,7 @@ map> Context::input_formats() { auto name = entry.first; auto input_format = entry.second; - result[name] = input_format->get_shared_pointer(this); + result[name] = input_format->get_shared_pointer(shared_from_this()); } return result; } @@ -183,7 +183,7 @@ map> Context::output_formats() { auto name = entry.first; auto output_format = entry.second; - result[name] = output_format->get_shared_pointer(this); + result[name] = output_format->get_shared_pointer(shared_from_this()); } return result; } @@ -779,7 +779,7 @@ vector> Trigger::stages() { vector> result; for (auto stage : _stages) - result.push_back(stage->get_shared_pointer(this)); + result.push_back(stage->get_shared_pointer(shared_from_this())); return result; } @@ -787,7 +787,7 @@ shared_ptr Trigger::add_stage() { auto stage = new TriggerStage(sr_trigger_stage_add(_structure)); _stages.push_back(stage); - return stage->get_shared_pointer(this); + return stage->get_shared_pointer(shared_from_this()); } TriggerStage::TriggerStage(struct sr_trigger_stage *structure) : @@ -810,7 +810,7 @@ vector> TriggerStage::matches() { vector> result; for (auto match : _matches) - result.push_back(match->get_shared_pointer(this)); + result.push_back(match->get_shared_pointer(shared_from_this())); return result; } @@ -925,7 +925,7 @@ shared_ptr Session::get_device(const struct sr_dev_inst *sdi) { if (_owned_devices.count(sdi)) return static_pointer_cast( - _owned_devices[sdi]->get_shared_pointer(this)); + _owned_devices[sdi]->get_shared_pointer(shared_from_this())); else if (_other_devices.count(sdi)) return _other_devices[sdi]; else @@ -1092,7 +1092,7 @@ const PacketType *Packet::type() const shared_ptr Packet::payload() { if (_payload) - return _payload->get_shared_pointer(this); + return _payload->get_shared_pointer(shared_from_this()); else throw Error(SR_ERR_NA); } @@ -1115,7 +1115,7 @@ Header::~Header() { } -shared_ptr Header::get_shared_pointer(Packet *_parent) +shared_ptr Header::get_shared_pointer(shared_ptr _parent) { return static_pointer_cast( ParentOwned::get_shared_pointer(_parent)); @@ -1143,7 +1143,7 @@ Meta::~Meta() { } -shared_ptr Meta::get_shared_pointer(Packet *_parent) +shared_ptr Meta::get_shared_pointer(shared_ptr _parent) { return static_pointer_cast( ParentOwned::get_shared_pointer(_parent)); @@ -1169,7 +1169,7 @@ Logic::~Logic() { } -shared_ptr Logic::get_shared_pointer(Packet *_parent) +shared_ptr Logic::get_shared_pointer(shared_ptr _parent) { return static_pointer_cast( ParentOwned::get_shared_pointer(_parent)); @@ -1200,7 +1200,7 @@ Analog::~Analog() { } -shared_ptr Analog::get_shared_pointer(Packet *_parent) +shared_ptr Analog::get_shared_pointer(shared_ptr _parent) { return static_pointer_cast( ParentOwned::get_shared_pointer(_parent)); @@ -1290,8 +1290,7 @@ shared_ptr InputFormat::create_input( auto input = sr_input_new(_structure, map_to_hash_variant(options)); if (!input) throw Error(SR_ERR_ARG); - return shared_ptr( - new Input(_parent->shared_from_this(), input), Input::Deleter()); + return shared_ptr(new Input(_parent, input), Input::Deleter()); } Input::Input(shared_ptr context, const struct sr_input *structure) : diff --git a/bindings/cxx/include/libsigrokcxx/libsigrokcxx.hpp b/bindings/cxx/include/libsigrokcxx/libsigrokcxx.hpp index a83600aa..38b71a6d 100644 --- a/bindings/cxx/include/libsigrokcxx/libsigrokcxx.hpp +++ b/bindings/cxx/include/libsigrokcxx/libsigrokcxx.hpp @@ -164,21 +164,14 @@ protected: { } -public: - /* Get parent object that owns this object. */ - shared_ptr parent() - { - return _parent; - } - /* Note, this implementation will create a new smart_ptr if none exists. */ shared_ptr shared_from_this() { - shared_ptr shared; + shared_ptr shared = _weak_this.lock(); - if (!(shared = _weak_this.lock())) + if (!shared) { - shared = shared_ptr(static_cast(this), reset_parent); + shared.reset(static_cast(this), &reset_parent); _weak_this = shared; } @@ -193,11 +186,11 @@ public: return shared_from_this(); } - shared_ptr get_shared_pointer(Parent *parent) +public: + /* Get parent object that owns this object. */ + shared_ptr parent() { - if (!parent) - throw Error(SR_ERR_BUG); - return get_shared_pointer(parent->shared_from_this()); + return _parent; } }; @@ -205,14 +198,6 @@ public: template class SR_API UserOwned : public enable_shared_from_this { -public: - shared_ptr shared_from_this() - { - auto shared = enable_shared_from_this::shared_from_this(); - if (!shared) - throw Error(SR_ERR_BUG); - return shared; - } protected: Struct *_structure; @@ -221,6 +206,14 @@ protected: { } + shared_ptr shared_from_this() + { + auto shared = enable_shared_from_this::shared_from_this(); + if (!shared) + throw Error(SR_ERR_BUG); + return shared; + } + /* Deleter needed to allow shared_ptr use with protected destructor. */ class Deleter { @@ -714,8 +707,15 @@ class SR_API PacketPayload protected: PacketPayload(); virtual ~PacketPayload() = 0; - virtual shared_ptr get_shared_pointer(Packet *parent) = 0; +private: + virtual shared_ptr get_shared_pointer(shared_ptr parent) = 0; + /** Deleter needed to allow shared_ptr use with protected destructor. */ + class Deleter + { + public: + void operator()(PacketPayload *payload) { delete payload; } + }; friend class Deleter; friend class Packet; friend class Output; @@ -734,7 +734,7 @@ public: private: explicit Header(const struct sr_datafeed_header *structure); ~Header(); - shared_ptr get_shared_pointer(Packet *parent); + shared_ptr get_shared_pointer(shared_ptr parent); friend class Packet; }; @@ -749,7 +749,7 @@ public: private: explicit Meta(const struct sr_datafeed_meta *structure); ~Meta(); - shared_ptr get_shared_pointer(Packet *parent); + shared_ptr get_shared_pointer(shared_ptr parent); map _config; friend class Packet; }; @@ -769,7 +769,7 @@ public: private: explicit Logic(const struct sr_datafeed_logic *structure); ~Logic(); - shared_ptr get_shared_pointer(Packet *parent); + shared_ptr get_shared_pointer(shared_ptr parent); friend class Packet; }; @@ -794,7 +794,7 @@ public: private: explicit Analog(const struct sr_datafeed_analog *structure); ~Analog(); - shared_ptr get_shared_pointer(Packet *parent); + shared_ptr get_shared_pointer(shared_ptr parent); friend class Packet; };