#include <RequestHandler.h>
#include <AssertUtils.h>
+#include <AtomicHelper.h>
#include <ResourceAttributesConverter.h>
+#include <ResourceAttributesUtils.h>
#include <logger.h>
#include <OCPlatform.h>
+#define LOG_TAG "RCSResourceObject"
+
namespace
{
using namespace OIC::Service;
- constexpr char LOG_TAG[]{ "RCSResourceObject" };
-
inline bool hasProperty(uint8_t base, uint8_t target)
{
return (base & target) == target;
}
catch (const OC::OCException& e)
{
- OC_LOG(WARNING, LOG_TAG, e.what());
+ OC_LOG_V(WARNING, LOG_TAG, "Error (%s)", e.what());
}
return OC_EH_ERROR;
m_setRequestHandler{ },
m_autoNotifyPolicy { AutoNotifyPolicy::UPDATED },
m_setRequestHandlerPolicy { SetRequestHandlerPolicy::NEVER },
- m_keyAttributesUpdatedListeners{ },
+ m_attributeUpdatedListeners{ },
m_lockOwner{ },
m_mutex{ },
- m_mutexKeyAttributeUpdate{ }
+ m_mutexAttributeUpdatedListeners{ }
{
+ m_lockOwner.reset(new AtomicThreadId);
}
RCSResourceObject::~RCSResourceObject()
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);
void RCSResourceObject::addAttributeUpdatedListener(const std::string& key,
AttributeUpdatedListener h)
{
- std::lock_guard<std::mutex> lock(m_mutexKeyAttributeUpdate);
- m_keyAttributesUpdatedListeners[key] = std::move(h);
+ std::lock_guard< std::mutex > lock(m_mutexAttributeUpdatedListeners);
+
+ m_attributeUpdatedListeners[key] =
+ std::make_shared< AttributeUpdatedListener >(std::move(h));
}
void RCSResourceObject::addAttributeUpdatedListener(std::string&& key,
AttributeUpdatedListener h)
{
- std::lock_guard<std::mutex> lock(m_mutexKeyAttributeUpdate);
- m_keyAttributesUpdatedListeners[std::move(key)] = std::move(h);
+ std::lock_guard< std::mutex > lock(m_mutexAttributeUpdatedListeners);
+
+ m_attributeUpdatedListeners[std::move(key)] =
+ std::make_shared< AttributeUpdatedListener >(std::move(h));
}
bool RCSResourceObject::removeAttributeUpdatedListener(const std::string& key)
{
- std::lock_guard<std::mutex> lock(m_mutexKeyAttributeUpdate);
+ std::lock_guard< std::mutex > lock(m_mutexAttributeUpdatedListeners);
- return m_keyAttributesUpdatedListeners.erase(key) != 0;
+ return m_attributeUpdatedListeners.erase(key) != 0;
}
bool RCSResourceObject::testValueUpdated(const std::string& key,
OCEntityHandlerResult RCSResourceObject::entityHandler(
std::shared_ptr< OC::OCResourceRequest > request)
{
+ OC_LOG(WARNING, LOG_TAG, "entityHandler");
if (!request)
{
return OC_EH_ERROR;
return sendResponse(*this, request, invokeHandler(attrs, request, m_getRequestHandler));
}
- OCEntityHandlerResult RCSResourceObject::handleRequestSet(
- std::shared_ptr< OC::OCResourceRequest > request)
+ bool RCSResourceObject::applyAcceptanceMethod(const RCSSetResponse& response,
+ const RCSResourceAttributes& requstAttrs)
{
- assert(request != nullptr);
-
- auto attrs = getAttributesFromOCRequest(request);
- auto response = invokeHandler(attrs, request, m_setRequestHandler);
auto requestHandler = response.getHandler();
assert(requestHandler != nullptr);
- AttrKeyValuePairs replaced = requestHandler->applyAcceptanceMethod(
- response.getAcceptanceMethod(), *this, attrs);
+ auto replaced = requestHandler->applyAcceptanceMethod(response.getAcceptanceMethod(),
+ *this, requstAttrs);
- for (const auto& it : replaced)
+ OC_LOG_V(WARNING, LOG_TAG, "replaced num %d", replaced.size());
+ for (const auto& attrKeyValPair : replaced)
{
- std::lock_guard<std::mutex> lock(m_mutexKeyAttributeUpdate);
+ std::shared_ptr< AttributeUpdatedListener > foundListener;
+ {
+ std::lock_guard< std::mutex > lock(m_mutexAttributeUpdatedListeners);
- auto keyAttribute = m_keyAttributesUpdatedListeners.find(it.first);
- if(keyAttribute != m_keyAttributesUpdatedListeners.end())
+ auto it = m_attributeUpdatedListeners.find(attrKeyValPair.first);
+ if (it != m_attributeUpdatedListeners.end())
+ {
+ foundListener = it->second;
+ }
+ }
+
+ if (foundListener)
{
- keyAttribute-> second(it.second, attrs[it.first]);
+ (*foundListener)(attrKeyValPair.second, requstAttrs.at(attrKeyValPair.first));
}
}
- autoNotify(!replaced.empty(), m_autoNotifyPolicy);
- return sendResponse(*this, request, response);
+ return !replaced.empty();
}
- OCEntityHandlerResult RCSResourceObject::handleObserve(
+ OCEntityHandlerResult RCSResourceObject::handleRequestSet(
std::shared_ptr< OC::OCResourceRequest > request)
{
assert(request != nullptr);
+ auto attrs = getAttributesFromOCRequest(request);
+ auto response = invokeHandler(attrs, request, m_setRequestHandler);
+
+ auto attrsChanged = applyAcceptanceMethod(response, attrs);
+
+ try
+ {
+ autoNotify(attrsChanged, m_autoNotifyPolicy);
+ return sendResponse(*this, request, response);
+ } catch (const RCSPlatformException& e) {
+ OC_LOG_V(ERROR, LOG_TAG, "Error : %s ", e.what());
+ return OC_EH_ERROR;
+ }
+ }
+
+ OCEntityHandlerResult RCSResourceObject::handleObserve(
+ std::shared_ptr< OC::OCResourceRequest >)
+ {
if (!isObservable())
{
return OC_EH_ERROR;
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,
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.m_lockOwner = std::this_thread::get_id();
+ m_resourceObject.setLockOwner(std::this_thread::get_id());
m_isOwningLock = true;
}
}
{
if (m_isOwningLock)
{
- m_resourceObject.m_lockOwner = std::thread::id{ };
+ m_resourceObject.setLockOwner(std::thread::id{ });
m_resourceObject.m_mutex.unlock();
}
}
{
return m_isOwningLock;
}
+
}
}