X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=service%2Fresource-encapsulation%2Fsrc%2Fcommon%2FprimitiveResource%2Finclude%2FAssertUtils.h;h=f556f39f92f6cb6e6cd484da735991fe3eb3657e;hb=390866079e285d2c74918432c0d597d5da52f8a0;hp=c91f9d9535405b2326035b26a1961e29ae4c968f;hpb=3e9402ad71cb3e93266a77796f44d17bab9853fd;p=platform%2Fupstream%2Fiotivity.git diff --git a/service/resource-encapsulation/src/common/primitiveResource/include/AssertUtils.h b/service/resource-encapsulation/src/common/primitiveResource/include/AssertUtils.h index c91f9d9..f556f39 100644 --- a/service/resource-encapsulation/src/common/primitiveResource/include/AssertUtils.h +++ b/service/resource-encapsulation/src/common/primitiveResource/include/AssertUtils.h @@ -22,13 +22,14 @@ #define COMMON_INTERNAL_ASSERTUTILS_H #include +#include #include -#include -#include +#include "octypes.h" +#include "OCException.h" -#include +#include "RCSException.h" namespace OIC { @@ -36,6 +37,47 @@ namespace OIC { namespace Detail { + + // This is a helper class to avoid calling the base layer during terminating the process. + // The reason why you should not call the base layer in this situation is that + // OC apis are singletons or internally implemented as singleton. + // Singleton implemented with a static variable is initialized + // in the first call to the function. + // It means you can not guarantee the order of initialization of the singletons, + // which is the reverse order of destruction. + // Some of RE classes are also implemented as singletons. + // Now we have a problem if RE tries to call one of OC apis + // after OC classes are destroyed first. + // To solve this issue, it registers exit handler to catch the termination event. + // Keep this information with a bool flag dynamically allocated to + // make sure it is not destroyed during the destruction of the static objects. + class TerminationChecker + { + private: + static bool& getExited() + { + static bool* flag = new bool{ false }; + return *flag; + } + + static void atExitHandler() + { + getExited() = true; + } + + TerminationChecker() + { + std::atexit(atExitHandler); + } + + public: + static bool isInTermination() + { + static TerminationChecker once; + return getExited(); + } + }; + struct NotOCStackResult; template @@ -105,6 +147,8 @@ namespace OIC invokeOCFuncWithResultExpect(std::initializer_list allowed, FUNC&& fn, PARAMS&& ...params) { + if (Detail::TerminationChecker::isInTermination()) return; + try { expectOCStackResult(fn(std::forward< PARAMS >(params)...), std::move(allowed)); @@ -121,6 +165,8 @@ namespace OIC OCStackResult >::type invokeOCFunc(FUNC&& fn, PARAMS&& ...params) { + if (Detail::TerminationChecker::isInTermination()) return; + try { expectOCStackResultOK(fn(std::forward< PARAMS >(params)...)); @@ -136,6 +182,8 @@ namespace OIC Detail::NotOCStackResult >::type invokeOCFunc(FUNC* fn, PARAMS&& ...params) { + if (Detail::TerminationChecker::isInTermination()) return; + try { return fn(std::forward< PARAMS >(params)...); @@ -153,6 +201,8 @@ namespace OIC decltype((obj->*fn)(std::forward< PARAMS >(params)...)), OCStackResult>:: type { + if (Detail::TerminationChecker::isInTermination()) return; + try { expectOCStackResultOK(obj->*fn(std::forward< PARAMS >(params)...)); @@ -171,6 +221,8 @@ namespace OIC Detail::NotOCStackResult>:: type { + if (Detail::TerminationChecker::isInTermination()) return; + try { obj->*fn(std::forward< PARAMS >(params)...); @@ -188,6 +240,8 @@ namespace OIC decltype((obj.get()->*fn)(std::forward< PARAMS >(params)...)), OCStackResult>:: type { + if (Detail::TerminationChecker::isInTermination()) return; + try { expectOCStackResultOK((obj.get()->*fn)(std::forward< PARAMS >(params)...)); @@ -206,6 +260,8 @@ namespace OIC Detail::NotOCStackResult>:: type { + if (Detail::TerminationChecker::isInTermination()) return { }; + try { return (obj.get()->*fn)(std::forward< PARAMS >(params)...);