From: Mu-Woong Lee Date: Thu, 28 Apr 2016 02:56:00 +0000 (+0900) Subject: Each provider handler is self-destructed if there is no remaining request X-Git-Tag: accepted/tizen/common/20160504.125342^2~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c9c83b8775fcbff00f21ab633bea31ae1b54774c;p=platform%2Fcore%2Fcontext%2Fcontext-service.git Each provider handler is self-destructed if there is no remaining request Change-Id: I688b0bd36cd56eb91e754d2a5acd55ab14996557 Signed-off-by: Mu-Woong Lee --- diff --git a/src/ProviderHandler.cpp b/src/ProviderHandler.cpp index a9521a2..c7ab57e 100644 --- a/src/ProviderHandler.cpp +++ b/src/ProviderHandler.cpp @@ -20,17 +20,23 @@ #include "Request.h" #include "ProviderHandler.h" +#define DELETE_DELAY 10 + using namespace ctx; std::map ProviderHandler::__instanceMap; -ProviderHandler::ProviderHandler(const char *subject) : - __subject(subject) +ProviderHandler::ProviderHandler(const std::string &subject) : + __subject(subject), + __deleteScheduled(false) { + _D("Subject: %s", __subject.c_str()); } ProviderHandler::~ProviderHandler() { + _D("Subject: %s", __subject.c_str()); + for (RequestInfo*& info : __subscribeRequests) { delete info; } @@ -45,7 +51,7 @@ ProviderHandler::~ProviderHandler() } /* TODO: Return proper error code */ -ProviderHandler* ProviderHandler::getInstance(const char *subject, bool force) +ProviderHandler* ProviderHandler::getInstance(std::string subject, bool force) { InstanceMap::iterator it = __instanceMap.find(subject); @@ -99,7 +105,7 @@ bool ProviderHandler::isAllowed(const Credentials *creds) void ProviderHandler::subscribe(RequestInfo *request) { - _I(CYAN("'%s' subscribes '%s' (RID-%d)"), request->getClient(), __subject, request->getId()); + _I(CYAN("'%s' subscribes '%s' (RID-%d)"), request->getClient(), __subject.c_str(), request->getId()); Json requestResult; int error = __provider->subscribe(request->getDescription().str(), &requestResult); @@ -114,7 +120,7 @@ void ProviderHandler::subscribe(RequestInfo *request) void ProviderHandler::unsubscribe(RequestInfo *request) { - _I(CYAN("'%s' unsubscribes '%s' (RID-%d)"), request->getClient(), __subject, request->getId()); + _I(CYAN("'%s' unsubscribes '%s' (RID-%d)"), request->getClient(), __subject.c_str(), request->getId()); /* Search the subscribe request to be removed */ auto target = __findRequest(__subscribeRequests, request->getClient(), request->getId()); @@ -145,11 +151,14 @@ void ProviderHandler::unsubscribe(RequestInfo *request) request->reply(error); delete request; delete reqFound; + + /* If idle, self destruct */ + __scheduleToDelete(); } void ProviderHandler::read(RequestInfo *request) { - _I(CYAN("'%s' reads '%s' (RID-%d)"), request->getClient(), __subject, request->getId()); + _I(CYAN("'%s' reads '%s' (RID-%d)"), request->getClient(), __subject.c_str(), request->getId()); Json requestResult; int error = __provider->read(request->getDescription().str(), &requestResult); @@ -164,13 +173,16 @@ void ProviderHandler::read(RequestInfo *request) void ProviderHandler::write(RequestInfo *request) { - _I(CYAN("'%s' writes '%s' (RID-%d)"), request->getClient(), __subject, request->getId()); + _I(CYAN("'%s' writes '%s' (RID-%d)"), request->getClient(), __subject.c_str(), request->getId()); Json requestResult; int error = __provider->write(request->getDescription(), &requestResult); request->reply(error, requestResult); delete request; + + /* If idle, self destruct */ + __scheduleToDelete(); } bool ProviderHandler::publish(Json &option, int error, Json &dataUpdated) @@ -205,15 +217,46 @@ bool ProviderHandler::replyToRead(Json &option, int error, Json &dataRead) __readRequests.erase(prev); } + /* If idle, self destruct */ + __scheduleToDelete(); + return true; } bool ProviderHandler::__loadProvider() { - __provider = __loader.load(__subject); + __provider = __loader.load(__subject.c_str()); return (__provider != NULL); } +bool ProviderHandler::__idle() +{ + return __subscribeRequests.empty() && __readRequests.empty(); +} + +void ProviderHandler::__scheduleToDelete() +{ + if (!__deleteScheduled && __idle()) { + __deleteScheduled = true; + g_timeout_add_seconds(DELETE_DELAY, __deletor, this); + _D("Delete scheduled for '%s' (%#x)", __subject.c_str(), this); + } +} + +gboolean ProviderHandler::__deletor(gpointer data) +{ + ProviderHandler *handle = static_cast(data); + + if (handle->__idle()) { + __instanceMap.erase(handle->__subject); + delete handle; + return FALSE; + } + + handle->__deleteScheduled = false; + return FALSE; +} + ProviderHandler::RequestList::iterator ProviderHandler::__findRequest(RequestList &reqList, Json &option) { diff --git a/src/ProviderHandler.h b/src/ProviderHandler.h index 634819e..a86e2ef 100644 --- a/src/ProviderHandler.h +++ b/src/ProviderHandler.h @@ -44,26 +44,32 @@ namespace ctx { bool publish(ctx::Json &option, int error, ctx::Json &dataUpdated); bool replyToRead(ctx::Json &option, int error, ctx::Json &dataRead); - static ProviderHandler* getInstance(const char *subject, bool force); + static ProviderHandler* getInstance(std::string subject, bool force); static void purge(); private: - const char *__subject; + std::string __subject; ContextProvider *__provider; RequestList __subscribeRequests; RequestList __readRequests; ProviderLoader __loader; + bool __deleteScheduled; static InstanceMap __instanceMap; - ProviderHandler(const char *subject); + ProviderHandler(const std::string &subject); ~ProviderHandler(); bool __loadProvider(); + bool __idle(); + void __scheduleToDelete(); + RequestList::iterator __findRequest(RequestList &reqList, Json &option); RequestList::iterator __findRequest(RequestList &reqList, std::string client, int reqId); RequestList::iterator __findRequest(RequestList::iterator begin, RequestList::iterator end, Json &option); + static gboolean __deletor(gpointer data); + }; /* class ProviderHandler */ } /* namespace ctx */ diff --git a/src/ProviderLoader.cpp b/src/ProviderLoader.cpp index e99ba10..b84ae93 100644 --- a/src/ProviderLoader.cpp +++ b/src/ProviderLoader.cpp @@ -55,7 +55,7 @@ ContextProvider* ProviderLoader::load(const char *subject) ContextProvider* ProviderLoader::__load(const char *soPath, const char *subject) { - _I("Load '%s' from '%s'", subject, soPath); + _SI("Load '%s' from '%s'", subject, soPath); __soHandle = dlopen(soPath, RTLD_LAZY | RTLD_GLOBAL); IF_FAIL_RETURN_TAG(__soHandle, NULL, _E, "%s", dlerror());