X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=service%2Fresource-encapsulation%2Fsrc%2FserverBuilder%2Fsrc%2FRCSResourceObject.cpp;h=ffbf5225ff8c9530d23d27ebb1030fcf729ce49b;hb=068b9d878cead4b54ceaba89cb9d9c19b1c5dcb1;hp=88c36a19cb6cc8cd7cebfaf6da60d3f8259a2fdf;hpb=aa6acd5905131fe90888bff37230cdd617098887;p=platform%2Fupstream%2Fiotivity.git diff --git a/service/resource-encapsulation/src/serverBuilder/src/RCSResourceObject.cpp b/service/resource-encapsulation/src/serverBuilder/src/RCSResourceObject.cpp old mode 100755 new mode 100644 index 88c36a1..ffbf522 --- a/service/resource-encapsulation/src/serverBuilder/src/RCSResourceObject.cpp +++ b/service/resource-encapsulation/src/serverBuilder/src/RCSResourceObject.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -75,14 +76,16 @@ namespace return OC_EH_ERROR; } - ResourceAttributes getAttributesFromOCRequest(std::shared_ptr< OC::OCResourceRequest > request) + RCSResourceAttributes getAttributesFromOCRequest( + std::shared_ptr< OC::OCResourceRequest > request) { return ResourceAttributesConverter::fromOCRepresentation( request->getResourceRepresentation()); } - template< typename HANDLER, typename RESPONSE = typename std::decay::type::result_type > - RESPONSE invokeHandler(ResourceAttributes& attrs, + template< typename HANDLER, typename RESPONSE = + typename std::decay::type::result_type > + RESPONSE invokeHandler(RCSResourceAttributes& attrs, std::shared_ptr< OC::OCResourceRequest > ocRequest, HANDLER&& handler) { if (handler) @@ -93,16 +96,17 @@ namespace return RESPONSE::defaultAction(); } - typedef void (RCSResourceObject::* AutoNotifyFunc)(bool, RCSResourceObject::AutoNotifyPolicy) const; + typedef void (RCSResourceObject::* AutoNotifyFunc) + (bool, RCSResourceObject::AutoNotifyPolicy) const; std::function createAutoNotifyInvoker(AutoNotifyFunc autoNotifyFunc, - const RCSResourceObject& resourceObject, const ResourceAttributes& resourceAttributes, + const RCSResourceObject& resourceObject, const RCSResourceAttributes& resourceAttributes, RCSResourceObject::AutoNotifyPolicy autoNotifyPolicy) { if(autoNotifyPolicy == RCSResourceObject::AutoNotifyPolicy::UPDATED) { auto&& compareAttributesFunc = - std::bind(std::not_equal_to(), + std::bind(std::not_equal_to(), resourceAttributes, std::cref(resourceAttributes)); return std::bind(autoNotifyFunc, @@ -148,14 +152,14 @@ namespace OIC } RCSResourceObject::Builder& RCSResourceObject::Builder::setAttributes( - const ResourceAttributes& attrs) + const RCSResourceAttributes& attrs) { m_resourceAttributes = attrs; return *this; } RCSResourceObject::Builder& RCSResourceObject::Builder::setAttributes( - ResourceAttributes&& attrs) + RCSResourceAttributes&& attrs) { m_resourceAttributes = std::move(attrs); return *this; @@ -171,18 +175,11 @@ namespace OIC OC::EntityHandler entityHandler{ std::bind(&RCSResourceObject::entityHandler, server.get(), std::placeholders::_1) }; - try - { - typedef OCStackResult (*RegisterResource)(OCResourceHandle&, std::string&, - const std::string&, const std::string&, OC::EntityHandler, uint8_t); + typedef OCStackResult (*RegisterResource)(OCResourceHandle&, std::string&, + const std::string&, const std::string&, OC::EntityHandler, uint8_t); - invokeOCFunc(static_cast(OC::OCPlatform::registerResource), - handle, m_uri, m_type, m_interface, entityHandler, m_properties); - } - catch (OC::OCException& e) - { - throw PlatformException(e.code()); - } + invokeOCFunc(static_cast(OC::OCPlatform::registerResource), + handle, m_uri, m_type, m_interface, entityHandler, m_properties); server->m_resourceHandle = handle; @@ -190,7 +187,7 @@ namespace OIC } - RCSResourceObject::RCSResourceObject(uint8_t properties, ResourceAttributes&& attrs) : + RCSResourceObject::RCSResourceObject(uint8_t properties, RCSResourceAttributes&& attrs) : m_properties { properties }, m_resourceHandle{ }, m_resourceAttributes{ std::move(attrs) }, @@ -203,6 +200,7 @@ namespace OIC m_mutex{ }, m_mutexKeyAttributeUpdate{ } { + m_lockOwner.reset(new AtomicThreadId); } RCSResourceObject::~RCSResourceObject() @@ -220,56 +218,52 @@ namespace OIC } } - void RCSResourceObject::setAttribute(const std::string& key, - const ResourceAttributes::Value& value) + template< typename K, typename V > + void RCSResourceObject::setAttributeInternal(K&& key, V&& value) { - WeakGuard lock(*this); + bool needToNotify = false; + bool valueUpdated = false; - if(lock.hasLocked()) { - autoNotifyIfNeeded(key, value); - } - - m_resourceAttributes[key] = value; - } + WeakGuard lock(*this); - void RCSResourceObject::setAttribute(const std::string& key, ResourceAttributes::Value&& value) - { - WeakGuard lock(*this); + if (lock.hasLocked()) + { + needToNotify = true; + valueUpdated = testValueUpdated(key, value); + } - if(lock.hasLocked()) - { - autoNotifyIfNeeded(key, value); + m_resourceAttributes[std::forward< K >(key)] = std::forward< V >(value); } - m_resourceAttributes[key] = std::move(value); + if (needToNotify) autoNotify(valueUpdated); } - - void RCSResourceObject::setAttribute(std::string&& key, const ResourceAttributes::Value& value) + void RCSResourceObject::setAttribute(const std::string& key, + const RCSResourceAttributes::Value& value) { - WeakGuard lock(*this); - - if(lock.hasLocked()) - { - autoNotifyIfNeeded(key, value); - } - - m_resourceAttributes[std::move(key)] = value; + setAttributeInternal(key, value); } - void RCSResourceObject::setAttribute(std::string&& key, ResourceAttributes::Value&& value) + void RCSResourceObject::setAttribute(const std::string& key, + RCSResourceAttributes::Value&& value) { - WeakGuard lock(*this); + setAttributeInternal(key, std::move(value)); + } - if(lock.hasLocked()) - { - autoNotifyIfNeeded(key, value); - } + void RCSResourceObject::setAttribute(std::string&& key, + const RCSResourceAttributes::Value& value) + { + setAttributeInternal(std::move(key), value); + } - m_resourceAttributes[std::move(key)] = std::move(value); + void RCSResourceObject::setAttribute(std::string&& key, + RCSResourceAttributes::Value&& value) + { + setAttributeInternal(std::move(key), std::move(value)); } - ResourceAttributes::Value RCSResourceObject::getAttributeValue(const std::string& key) const + RCSResourceAttributes::Value RCSResourceObject::getAttributeValue( + const std::string& key) const { WeakGuard lock(*this); return m_resourceAttributes.at(key); @@ -277,13 +271,21 @@ namespace OIC bool RCSResourceObject::removeAttribute(const std::string& key) { - WeakGuard lock(*this); - if (m_resourceAttributes.erase(key)) + bool needToNotify = false; + bool erased = false; { - autoNotify(true, getAutoNotifyPolicy()); - return true; + WeakGuard lock(*this); + + if (m_resourceAttributes.erase(key)) + { + erased = true; + needToNotify = lock.hasLocked(); + } } - return false; + + if (needToNotify) autoNotify(true); + + return erased; } bool RCSResourceObject::containsAttribute(const std::string& key) const @@ -292,13 +294,13 @@ namespace OIC return m_resourceAttributes.contains(key); } - ResourceAttributes& RCSResourceObject::getAttributes() + RCSResourceAttributes& RCSResourceObject::getAttributes() { expectOwnLock(); return m_resourceAttributes; } - const ResourceAttributes& RCSResourceObject::getAttributes() const + const RCSResourceAttributes& RCSResourceObject::getAttributes() const { expectOwnLock(); return m_resourceAttributes; @@ -306,12 +308,22 @@ namespace OIC void RCSResourceObject::expectOwnLock() const { - if (m_lockOwner != std::this_thread::get_id()) + if (getLockOwner() != std::this_thread::get_id()) { throw NoLockException{ "Must acquire the lock first using LockGuard." }; } } + std::thread::id RCSResourceObject::getLockOwner() const noexcept + { + return *m_lockOwner; + } + + void RCSResourceObject::setLockOwner(std::thread::id&& id) const noexcept + { + m_lockOwner->store(std::move(id)); + } + bool RCSResourceObject::isObservable() const { return ::hasProperty(m_properties, OC_OBSERVABLE); @@ -336,8 +348,7 @@ namespace OIC { typedef OCStackResult (*NotifyAllObservers)(OCResourceHandle); - invokeOCFuncWithResultExpect( - { OC_STACK_OK, OC_STACK_NO_OBSERVERS }, + invokeOCFuncWithResultExpect({ OC_STACK_OK, OC_STACK_NO_OBSERVERS }, static_cast< NotifyAllObservers >(OC::OCPlatform::notifyAllObservers), m_resourceHandle); } @@ -359,15 +370,15 @@ namespace OIC bool RCSResourceObject::removeAttributeUpdatedListener(const std::string& key) { std::lock_guard lock(m_mutexKeyAttributeUpdate); - return (bool) m_keyAttributesUpdatedListeners.erase(key); + + return m_keyAttributesUpdatedListeners.erase(key) != 0; } - void RCSResourceObject::autoNotifyIfNeeded(const std::string& key, - const ResourceAttributes::Value& value) + bool RCSResourceObject::testValueUpdated(const std::string& key, + const RCSResourceAttributes::Value& value) const { - autoNotify( m_resourceAttributes.contains(key) == false - || m_resourceAttributes.at(key) != value - , m_autoNotifyPolicy); + return m_resourceAttributes.contains(key) == false + || m_resourceAttributes.at(key) != value; } void RCSResourceObject::setAutoNotifyPolicy(AutoNotifyPolicy policy) @@ -385,16 +396,23 @@ namespace OIC m_setRequestHandlerPolicy = policy; } - RCSResourceObject::SetRequestHandlerPolicy RCSResourceObject::getSetRequestHandlerPolicy() const + auto RCSResourceObject::getSetRequestHandlerPolicy() const -> SetRequestHandlerPolicy { return m_setRequestHandlerPolicy; } + void RCSResourceObject::autoNotify(bool isAttributesChanged) const + { + autoNotify(isAttributesChanged, m_autoNotifyPolicy); + } + void RCSResourceObject::autoNotify( bool isAttributesChanged, AutoNotifyPolicy autoNotifyPolicy) const { if(autoNotifyPolicy == AutoNotifyPolicy::NEVER) return; - if(autoNotifyPolicy == AutoNotifyPolicy::UPDATED && isAttributesChanged == false) return; + if(autoNotifyPolicy == AutoNotifyPolicy::UPDATED && + isAttributesChanged == false) return; + notify(); } @@ -474,14 +492,14 @@ namespace OIC AttrKeyValuePairs replaced = requestHandler->applyAcceptanceMethod( response.getAcceptanceMethod(), *this, attrs); - for (const auto& it : replaced) + for (const auto& attrKeyValPair : replaced) { std::lock_guard lock(m_mutexKeyAttributeUpdate); - auto keyAttribute = m_keyAttributesUpdatedListeners.find(it.first); - if(keyAttribute != m_keyAttributesUpdatedListeners.end()) + auto keyAttrListener = m_keyAttributesUpdatedListeners.find(attrKeyValPair.first); + if(keyAttrListener != m_keyAttributesUpdatedListeners.end()) { - keyAttribute-> second(it.second, attrs[it.first]); + keyAttrListener-> second(attrKeyValPair.second, attrs[attrKeyValPair.first]); } } @@ -490,10 +508,8 @@ namespace OIC } OCEntityHandlerResult RCSResourceObject::handleObserve( - std::shared_ptr< OC::OCResourceRequest > request) + std::shared_ptr< OC::OCResourceRequest >) { - assert(request != nullptr); - if (!isObservable()) { return OC_EH_ERROR; @@ -530,9 +546,9 @@ namespace OIC RCSResourceObject::LockGuard::LockGuard( const RCSResourceObject& resourceObject, AutoNotifyPolicy autoNotifyPolicy) : - m_resourceObject(resourceObject), - m_autoNotifyPolicy { autoNotifyPolicy }, - m_isOwningLock{ false } + m_resourceObject(resourceObject), + m_autoNotifyPolicy { autoNotifyPolicy }, + m_isOwningLock{ false } { init(); } @@ -543,17 +559,17 @@ namespace OIC if (m_isOwningLock) { - m_resourceObject.m_lockOwner = std::thread::id{ }; + m_resourceObject.setLockOwner(std::thread::id{ }); m_resourceObject.m_mutex.unlock(); } } void RCSResourceObject::LockGuard::init() { - if (m_resourceObject.m_lockOwner != std::this_thread::get_id()) + if (m_resourceObject.getLockOwner() != std::this_thread::get_id()) { m_resourceObject.m_mutex.lock(); - m_resourceObject.m_lockOwner = std::this_thread::get_id(); + m_resourceObject.setLockOwner(std::this_thread::get_id()); m_isOwningLock = true; } m_autoNotifyFunc = ::createAutoNotifyInvoker(&RCSResourceObject::autoNotify, @@ -565,9 +581,10 @@ namespace OIC m_isOwningLock{ false }, m_resourceObject(resourceObject) { - if (resourceObject.m_lockOwner != std::this_thread::get_id()) + if (m_resourceObject.getLockOwner() != std::this_thread::get_id()) { m_resourceObject.m_mutex.lock(); + m_resourceObject.setLockOwner(std::this_thread::get_id()); m_isOwningLock = true; } } @@ -576,6 +593,7 @@ namespace OIC { if (m_isOwningLock) { + m_resourceObject.setLockOwner(std::thread::id{ }); m_resourceObject.m_mutex.unlock(); } } @@ -584,5 +602,6 @@ namespace OIC { return m_isOwningLock; } + } }