From: coderhyme Date: Tue, 28 Jul 2015 05:29:18 +0000 (+0900) Subject: Fix a callback problem of PrimitiveResource X-Git-Tag: 1.0.0-RC1~242 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=957bb6b53e9cb60dbfb49b7c37f5a364afb3a5e5;p=contrib%2Fiotivity.git Fix a callback problem of PrimitiveResource The problem was calling the callback even after the object for it was gone. PrimitiveResource is only created with shared_ptr and callbacks are async operations. When received the response, there is a possibility that no one holds the resource. Now checks the object is alive before executing the callback. Change-Id: I07b20d251c2b8544e7d27f354193b53c910d579c Signed-off-by: coderhyme Reviewed-on: https://gerrit.iotivity.org/gerrit/1950 Tested-by: jenkins-iotivity Reviewed-by: Madan Lanka --- diff --git a/service/resource-encapsulation/src/common/primitiveResource/include/PrimitiveResource.h b/service/resource-encapsulation/src/common/primitiveResource/include/PrimitiveResource.h index ca7f5b7..7b36f4f 100644 --- a/service/resource-encapsulation/src/common/primitiveResource/include/PrimitiveResource.h +++ b/service/resource-encapsulation/src/common/primitiveResource/include/PrimitiveResource.h @@ -41,10 +41,11 @@ namespace OIC class RCSResourceAttributes; class ResponseStatement; - class PrimitiveResource + class PrimitiveResource: public std::enable_shared_from_this< PrimitiveResource > { public: - typedef std::shared_ptr Ptr; + typedef std::shared_ptr< PrimitiveResource > Ptr; + typedef std::shared_ptr< const PrimitiveResource > ConstPtr; typedef std::function GetCallback; diff --git a/service/resource-encapsulation/src/common/primitiveResource/include/PrimitiveResourceImpl.h b/service/resource-encapsulation/src/common/primitiveResource/include/PrimitiveResourceImpl.h index ccf72ca..fb22426 100644 --- a/service/resource-encapsulation/src/common/primitiveResource/include/PrimitiveResourceImpl.h +++ b/service/resource-encapsulation/src/common/primitiveResource/include/PrimitiveResourceImpl.h @@ -40,10 +40,48 @@ namespace OIC private: static ResponseStatement createResponseStatement( - const OC::OCRepresentation& ocRepresentation) + const OC::OCRepresentation& rep) { return ResponseStatement::create( - ResourceAttributesConverter::fromOCRepresentation(ocRepresentation)); + ResourceAttributesConverter::fromOCRepresentation(rep)); + } + + template< typename CALLBACK, typename ...ARGS > + static inline void checkedCall(const std::weak_ptr< const PrimitiveResource >& resource, + const CALLBACK& cb, ARGS&&... args) + { + auto checkedRes = resource.lock(); + + if (!checkedRes) return; + + cb(std::forward< ARGS >(args)...); + } + + template< typename CALLBACK > + static void safeCallback(const std::weak_ptr< const PrimitiveResource >& resource, + const CALLBACK& cb, const HeaderOptions& headerOptions, + const OC::OCRepresentation& rep, int errorCode) + { + checkedCall(resource, cb, headerOptions, createResponseStatement(rep), errorCode); + } + + static void safeObserveCallback(const std::weak_ptr< const PrimitiveResource >& res, + const PrimitiveResource::ObserveCallback& cb, + const HeaderOptions& headerOptions, const OC::OCRepresentation& rep, + int errorCode, int sequenceNumber) + { + checkedCall(res, cb, headerOptions, createResponseStatement(rep), errorCode, + sequenceNumber); + } + + std::weak_ptr< PrimitiveResource > WeakFromThis() + { + return shared_from_this(); + } + + std::weak_ptr< const PrimitiveResource > WeakFromThis() const + { + return shared_from_this(); } public: @@ -60,8 +98,9 @@ namespace OIC const OC::QueryParamsMap&, OC::GetCallback); invokeOC(m_baseResource, static_cast< GetFunc >(&BaseResource::get), - OC::QueryParamsMap(), std::bind(std::move(callback), _1, - std::bind(createResponseStatement, _2), _3)); + OC::QueryParamsMap{ }, + std::bind(safeCallback< GetCallback >, WeakFromThis(), + std::move(callback), _1, _2, _3)); } void requestSet(const RCSResourceAttributes& attrs, SetCallback callback) @@ -74,8 +113,9 @@ namespace OIC invokeOC(m_baseResource, static_cast< PutFunc >(&BaseResource::put), ResourceAttributesConverter::toOCRepresentation(attrs), - OC::QueryParamsMap{ }, std::bind(std::move(callback), _1, - std::bind(createResponseStatement, _2), _3)); + OC::QueryParamsMap{ }, + std::bind(safeCallback< SetCallback >, WeakFromThis(), + std::move(callback), _1, _2, _3)); } void requestObserve(ObserveCallback callback) @@ -87,7 +127,8 @@ namespace OIC invokeOC(m_baseResource, static_cast< ObserveFunc >(&BaseResource::observe), OC::ObserveType::ObserveAll, OC::QueryParamsMap{ }, - bind(std::move(callback), _1, bind(createResponseStatement, _2), _3, _4)); + std::bind(safeObserveCallback, WeakFromThis(), + std::move(callback), _1, _2, _3, _4)); } void cancelObserve()