From a31834d16272a5b8d3382fb2959676804157c732 Mon Sep 17 00:00:00 2001 From: Erich Keane Date: Fri, 9 Jan 2015 16:53:28 -0800 Subject: [PATCH] Fixed InProcServerWrapper to be thread safe A few of the variables/collections in the server wrapper were not properly protected against multi-threading. This fix adds a mutex to the class to ensure that all accessed items are protected. Additionally, they are moved out of the root namespace to prevent polution. Change-Id: I2eedb9bf9b1960ff7a018a2ca1e15183e42bd9cd Signed-off-by: Erich Keane --- resource/src/InProcServerWrapper.cpp | 63 +++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/resource/src/InProcServerWrapper.cpp b/resource/src/InProcServerWrapper.cpp index 0159bb8..d60f613 100644 --- a/resource/src/InProcServerWrapper.cpp +++ b/resource/src/InProcServerWrapper.cpp @@ -39,9 +39,16 @@ using namespace std; using namespace OC; -std::map entityHandlerMap; -std::map resourceUriMap; -EntityHandler defaultDeviceEntityHandler = 0; +namespace OC +{ + namespace details + { + std::mutex serverWrapperLock; + std::map entityHandlerMap; + std::map resourceUriMap; + EntityHandler defaultDeviceEntityHandler = 0; + } +} void formResourceRequest(OCEntityHandlerFlag flag, OCEntityHandlerRequest * entityHandlerRequest, @@ -150,9 +157,15 @@ OCEntityHandlerResult DefaultEntityHandlerWrapper(OCEntityHandlerFlag flag, pRequest->setResourceUri(std::string(uri)); - if(defaultDeviceEntityHandler) + EntityHandler defHandler; + { + std::lock_guard lock(OC::details::serverWrapperLock); + defHandler = OC::details::defaultDeviceEntityHandler; + } + + if(defHandler) { - result = defaultDeviceEntityHandler(pRequest); + result = defHandler(pRequest); } else { @@ -181,9 +194,15 @@ OCEntityHandlerResult EntityHandlerWrapper(OCEntityHandlerFlag flag, formResourceRequest(flag, entityHandlerRequest, pRequest); + std::map ::iterator resourceUriEntry; + std::map ::iterator resourceUriEnd; + { + std::lock_guard lock(OC::details::serverWrapperLock); + resourceUriEntry = OC::details::resourceUriMap.find(entityHandlerRequest->resource); + resourceUriEnd = OC::details::resourceUriMap.end(); + } // Finding the corresponding URI for a resource handle and set the URI in the request - auto resourceUriEntry = resourceUriMap.find(entityHandlerRequest->resource); - if(resourceUriEntry != resourceUriMap.end()) + if(resourceUriEntry != resourceUriEnd) { pRequest->setResourceUri(resourceUriEntry->second); } @@ -193,10 +212,16 @@ OCEntityHandlerResult EntityHandlerWrapper(OCEntityHandlerFlag flag, return OC_EH_ERROR; } - // Finding the corresponding CPP Application entityHandler for a given resource - auto entityHandlerEntry = entityHandlerMap.find(entityHandlerRequest->resource); + std::map ::iterator entityHandlerEntry; + std::map ::iterator entityHandlerEnd; + { + // Finding the corresponding CPP Application entityHandler for a given resource + std::lock_guard lock(OC::details::serverWrapperLock); + entityHandlerEntry = OC::details::entityHandlerMap.find(entityHandlerRequest->resource); + entityHandlerEnd = OC::details::entityHandlerMap.end(); + } - if(entityHandlerEntry != entityHandlerMap.end()) + if(entityHandlerEntry != entityHandlerEnd) { // Call CPP Application Entity Handler if(entityHandlerEntry->second) @@ -327,8 +352,9 @@ namespace OC } else { - entityHandlerMap[resourceHandle] = eHandler; - resourceUriMap[resourceHandle] = resourceURI; + std::lock_guard lock(OC::details::serverWrapperLock); + OC::details::entityHandlerMap[resourceHandle] = eHandler; + OC::details::resourceUriMap[resourceHandle] = resourceURI; } } else @@ -386,8 +412,9 @@ namespace OC } else { - entityHandlerMap[resourceHandle] = eHandler; - resourceUriMap[resourceHandle] = resourceURI; + std::lock_guard lock(OC::details::serverWrapperLock); + OC::details::entityHandlerMap[resourceHandle] = eHandler; + OC::details::resourceUriMap[resourceHandle] = resourceURI; } } else @@ -403,7 +430,10 @@ namespace OC { OCStackResult result = OC_STACK_ERROR; - defaultDeviceEntityHandler = entityHandler; + { + std::lock_guard lock(OC::details::serverWrapperLock); + OC::details::defaultDeviceEntityHandler = entityHandler; + } if(entityHandler) { @@ -430,7 +460,8 @@ namespace OC if(result == OC_STACK_OK) { - resourceUriMap.erase(resourceHandle); + std::lock_guard lock(OC::details::serverWrapperLock); + OC::details::resourceUriMap.erase(resourceHandle); } else { -- 2.7.4