X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fserver%2Fworker_thread.cc;h=b623a2c112c5d7dd3b9f022303cd37ee4fd46b4c;hb=54073ac20bd49b3d664527b7f13b04290152e268;hp=5cb648fb48a20d69461568f255aa050a7e78aec4;hpb=10e8d551161599c7ab7cb436dfcfe1672d63b12d;p=platform%2Fcore%2Fappfw%2Fpkgmgr-info.git diff --git a/src/server/worker_thread.cc b/src/server/worker_thread.cc index 5cb648f..b623a2c 100644 --- a/src/server/worker_thread.cc +++ b/src/server/worker_thread.cc @@ -14,22 +14,23 @@ * limitations under the License. */ +#include "worker_thread.hh" + #include +#include #include -#include "worker_thread.hh" -#include "db_handle_provider.hh" +#include -#include "pkgmgrinfo_debug.h" -#include "get_appinfo_request_handler.hh" -#include "get_cert_request_handler.hh" -#include "get_pkginfo_request_handler.hh" -#include "get_depinfo_request_handler.hh" -#include "query_request_handler.hh" -#include "set_cert_request_handler.hh" -#include "set_pkginfo_request_handler.hh" #include "abstract_parcelable.hh" -#include "command_request_handler.hh" +#include "cynara_checker.hh" +#include "db_change_observer.hh" +#include "request_handler_factory.hh" +#include "server/database/db_handle_provider.hh" +#include "server/database/update_pending_cache_handler.hh" +#include "utils/logging.hh" + +#include "pkgmgrinfo_debug.h" #ifdef LOG_TAG #undef LOG_TAG @@ -40,6 +41,39 @@ #define SQLITE_ENABLE_MEMORY_MANAGEMENT #endif +namespace { + +uid_t globaluser_uid = -1; + +uid_t GetGlobalUID() { + if (globaluser_uid == (uid_t)-1) + globaluser_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER); + + return globaluser_uid; +} + +uid_t ConvertUID(uid_t uid) { + if (uid < REGULAR_USER) + return GetGlobalUID(); + else + return uid; +} + +const char PRIVILEGE_PACKAGE_MANAGER_ADMIN[] = + "http://tizen.org/privilege/packagemanager.admin"; + +std::vector GetPrivileges(pkgmgr_common::ReqType type) { + std::vector ret; + if (type == pkgmgr_common::SET_CERT_INFO) + ret.emplace_back(PRIVILEGE_PACKAGE_MANAGER_ADMIN); + else if (type == pkgmgr_common::SET_PKG_INFO) + ret.emplace_back(PRIVILEGE_PACKAGE_MANAGER_ADMIN); + + return ret; +} + +} // namespace + namespace pkgmgr_server { WorkerThread::WorkerThread(unsigned int num) : stop_all_(false) { @@ -47,7 +81,7 @@ WorkerThread::WorkerThread(unsigned int num) : stop_all_(false) { for (unsigned int i = 0; i < num; ++i) threads_.emplace_back([this]() -> void { this->Run(); }); - LOGD("%d Worker threads are created", num); + LOG(DEBUG) << num << " Worker threads are created"; } WorkerThread::~WorkerThread() { @@ -67,121 +101,125 @@ bool WorkerThread::PushQueue(std::shared_ptr req) { return true; } +std::shared_ptr WorkerThread::PopQueue() { + SetMemoryTrimTimer(); + std::unique_lock u(lock_); + cv_.wait(u, [this] { return !this->queue_.empty() || stop_all_; }); + if (stop_all_ && queue_.empty()) + return nullptr; + + auto req = queue_.front(); + queue_.pop(); + return req; +} + void WorkerThread::Run() { - std::unique_ptr - handler[pkgmgr_common::ReqType::MAX]; - handler[pkgmgr_common::ReqType::GET_PKG_INFO].reset( - new request_handler::GetPkginfoRequestHandler()); - handler[pkgmgr_common::ReqType::GET_APP_INFO].reset( - new request_handler::GetAppinfoRequestHandler()); - handler[pkgmgr_common::ReqType::SET_PKG_INFO].reset( - new request_handler::SetPkginfoRequestHandler()); - handler[pkgmgr_common::ReqType::SET_CERT_INFO].reset( - new request_handler::SetCertRequestHandler()); - handler[pkgmgr_common::ReqType::GET_CERT_INFO].reset( - new request_handler::GetCertRequestHandler()); - handler[pkgmgr_common::ReqType::GET_PKG_DEP_INFO].reset( - new request_handler::GetDepinfoRequestHandler()); - handler[pkgmgr_common::ReqType::QUERY].reset( - new request_handler::QueryRequestHandler()); - handler[pkgmgr_common::ReqType::COMMAND].reset( - new request_handler::CommandRequestHandler()); - - LOGD("Initialize request handlers"); + RequestHandlerFactory factory; + LOG(DEBUG) << "Initialize request handlers"; while (true) { - std::shared_ptr req; - { - std::unique_lock u(lock_); - cv_.wait(u, [this] { return !this->queue_.empty() || stop_all_; }); - if (stop_all_ && queue_.empty()) - return; - req = PopQueue(); + std::shared_ptr req = PopQueue(); + if (req == nullptr) + return; + + if (!req->GetPrivilegeChecked()) { + if (!req->ReceiveData()) { + LOG(ERROR) << "Fail to receive data"; + continue; + } + + pkgmgr_common::ReqType type = req->GetRequestType(); + if (pkgmgr_common::IsDbWriteRequest(type)) + StopDbChangeListening(); + std::vector privileges = GetPrivileges(type); + if (!CynaraChecker::GetInst().CheckPrivilege(this, req, privileges)) + continue; } - if (req->ReceiveData() == false) { - LOGE("Failed to ReceiveData"); - continue; - } - pkgmgr_common::ReqType type = req->GetRequestType(); - LOGD("Request type(%s), pid(%d)", - pkgmgr_common::ReqTypeToString(type).c_str(), req->GetSenderPID()); - if (type <= pkgmgr_common::ReqType::REQ_TYPE_NONE - || type >= pkgmgr_common::ReqType::MAX) { - LOGE("Request type is invalid (%d)", static_cast(type)); - - pkgmgr_common::parcel::AbstractParcelable parcelable( - 0, pkgmgr_common::parcel::ParcelableType::Unknown, PMINFO_R_ERROR); - tizen_base::Parcel p; - p.WriteParcelable(parcelable); - std::vector raw = p.GetRaw(); - req->SendData(&raw[0], raw.size()); + auto type = req->GetRequestType(); + LOG(WARNING) << "Request type: " << pkgmgr_common::ReqTypeToString(type) + << " pid: " << req->GetSenderPID() << " tid: " << req->GetSenderTID(); + auto handler = factory.GetRequestHandler(type); + if (handler == nullptr) continue; - } try { - handler[type]->SetPID(req->GetSenderPID()); - if (!handler[type]->HandleRequest(req->GetData(), req->GetSize(), - locale_.GetObject())) - LOGE("Failed to handle request"); + handler->PreExec(); + handler->SetUID(ConvertUID(req->GetSenderUID())); + handler->SetPID(req->GetSenderPID()); + if (!handler->HandleRequest(req->DetachData(), req->GetSize(), + locale_.GetObject())) + LOG(ERROR) << "Failed to handle request"; + + if (req->SendData(handler->ExtractResult()) == false) + LOG(ERROR) << "Failed to send response pid: " << req->GetSenderPID(); + else + LOG(WARNING) << "Success response pid: " << req->GetSenderPID() + << " tid: " << req->GetSenderTID(); } catch (const std::exception& err) { - LOGE("Exception occurred (%s)", err.what()); - pkgmgr_common::parcel::AbstractParcelable parcelable( - 0, pkgmgr_common::parcel::ParcelableType::Unknown, PMINFO_R_ERROR); - tizen_base::Parcel p; - p.WriteParcelable(parcelable); - std::vector raw = p.GetRaw(); - req->SendData(&raw[0], raw.size()); - continue; + LOG(ERROR) << "Exception occurred: " << err.what() + << ", pid: " << req->GetSenderPID(); + SendError(req); } catch (...) { - LOGE("Exception occurred"); - pkgmgr_common::parcel::AbstractParcelable parcelable( - 0, pkgmgr_common::parcel::ParcelableType::Unknown, PMINFO_R_ERROR); - tizen_base::Parcel p; - p.WriteParcelable(parcelable); - std::vector raw = p.GetRaw(); - req->SendData(&raw[0], raw.size()); - continue; + LOG(ERROR) << "Exception occurred pid: " << req->GetSenderPID(); + SendError(req); } - std::vector result_data = handler[type]->ExtractResult(); - req->SendData(result_data.data(), result_data.size()); + handler->PostExec(); } } void WorkerThread::SetMemoryTrimTimer() { - static guint timer = 0; - if (timer > 0) - g_source_remove(timer); + std::lock_guard lock(mutex_); + if (timer_ > 0) + g_source_remove(timer_); - timer = g_timeout_add_seconds_full(G_PRIORITY_LOW, 3, - TrimMemory, &timer, NULL); + timer_ = g_timeout_add_seconds_full(G_PRIORITY_LOW, 10, + TrimMemory, this, NULL); } gboolean WorkerThread::TrimMemory(void* data) { - LOGD("Trim memory"); - guint* timer = static_cast(data); + LOG(DEBUG) << "Trim memory"; + auto* h = static_cast(data); + { + std::lock_guard lock(h->mutex_); + h->timer_ = 0; + } + + auto crashed_writer_pids = + database::DBHandleProvider::CrashedWriteRequestPIDs(); + if (!crashed_writer_pids.empty()) { + database::UpdatePendingCacheHandler db(getuid(), std::move(crashed_writer_pids), {}); + db.SetLocale(h->locale_.GetObject()); + db.Execute(); + } + sqlite3_release_memory(-1); malloc_trim(0); - *timer = 0; - - if (pkgmgr_common::DBHandleProvider::IsCrashedWriteRequest()) - pkgmgr_common::DBHandleProvider:: - GetInst(getuid()).SetMemoryMode(getpid(), false); + return G_SOURCE_REMOVE; +} - return false; +void WorkerThread::SetLocale(std::string locale) { + LOG(DEBUG) << "Change locale : " << locale_.GetObject() + << " -> " << locale; + locale_.SetObject(std::move(locale)); } -std::shared_ptr WorkerThread::PopQueue() { - SetMemoryTrimTimer(); - auto req = queue_.front(); - queue_.pop(); - return req; +void WorkerThread::SendError(const std::shared_ptr& req) { + pkgmgr_common::parcel::AbstractParcelable parcelable( + 0, pkgmgr_common::parcel::ParcelableType::Unknown, PMINFO_R_ERROR); + tizen_base::Parcel p; + p.WriteParcelable(parcelable); + req->SendData(p); } -void WorkerThread::SetLocale(std::string locale) { - LOGD("Change locale (%s) -> (%s)", locale_.GetObject().c_str(), - locale.c_str()); - locale_.SetObject(std::move(locale)); +void WorkerThread::StopDbChangeListening() { + auto& db_observer = pkgmgr_common::DbChangeObserver::GetInst(); + + if (db_observer.GetDisposed()) + return; + + LOG(WARNING) << "Try stop listening db change"; + db_observer.StopListening(); } } // namespace pkgmgr_server