Refactor pkgmgr-info 49/269349/14
authorJunghyun Yeon <jungh.yeon@samsung.com>
Thu, 13 Jan 2022 04:26:28 +0000 (13:26 +0900)
committerJunghyun Yeon <jungh.yeon@samsung.com>
Fri, 8 Apr 2022 07:20:56 +0000 (16:20 +0900)
- Separace Cache logic from DBHandleProvider.
- Change function name for readability.
- Add UID setter/getter function at AbstractRequestHandler to provide uid at CacheRequestHandler.
- Apply early-return policy to reduce indentation.

Change-Id: I1f2bc50247178a70c2268c81d2f2fc5bd2e75b2c
Signed-off-by: Junghyun Yeon <jungh.yeon@samsung.com>
19 files changed:
src/manager/pkginfo_manager.cc
src/server/cache_flag.hh [deleted file]
src/server/database/appinfo_db_handler.cc
src/server/database/appinfo_db_handler.hh
src/server/database/cache.cc [new file with mode: 0644]
src/server/database/cache.hh [new file with mode: 0644]
src/server/database/cache_db_handler.cc
src/server/database/cache_provider.cc [new file with mode: 0644]
src/server/database/cache_provider.hh [new file with mode: 0644]
src/server/database/db_handle_provider.cc
src/server/database/db_handle_provider.hh
src/server/database/pkg_get_db_handler.cc
src/server/database/pkg_get_db_handler.hh
src/server/database/query_handler.cc
src/server/request_handler/abstract_request_handler.cc
src/server/request_handler/abstract_request_handler.hh
src/server/request_handler/create_cache_request_handler.cc
src/server/runner.cc
src/server/worker_thread.cc

index 2b72d05..d88d2a3 100644 (file)
@@ -120,9 +120,10 @@ extern "C" EXPORT_API int _pkginfo_get_packages(uid_t uid,
     LOG(DEBUG) << "No packages meets given condition for user " << uid;
     return PMINFO_R_ENOENT;
   }
-  for (auto& pkginfo : result_list)
+  for (auto& pkginfo : result_list) {
     g_hash_table_insert(packages, reinterpret_cast<gpointer>(pkginfo->package),
                         reinterpret_cast<gpointer>(pkginfo.get()));
+  }
 
   return PMINFO_R_OK;
 }
@@ -186,9 +187,10 @@ extern "C" EXPORT_API int _appinfo_get_applications(uid_t uid,
       std::static_pointer_cast<pcp::AppInfoParcelable>(ptr));
 
   std::vector<std::shared_ptr<application_x>> result_list = return_parcel->ExtractAppInfo();
-  for (auto& app : result_list)
+  for (auto& app : result_list) {
     g_hash_table_insert(packages, reinterpret_cast<gpointer>(app->appid),
         reinterpret_cast<gpointer>(app.get()));
+  }
 
   return PMINFO_R_OK;
 }
diff --git a/src/server/cache_flag.hh b/src/server/cache_flag.hh
deleted file mode 100644 (file)
index 67aa9a0..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef CACHE_FLAG_HH_
-#define CACHE_FLAG_HH_
-
-#include <mutex>
-#include <shared_mutex>
-
-namespace pkgmgr_server {
-
-#ifndef EXPORT_API
-#define EXPORT_API __attribute__((visibility("default")))
-#endif
-
-class EXPORT_API CacheFlag {
- public:
-  enum class EXPORT_API Status {
-    UNPREPARED,
-    PREPARING,
-    PREPARED
-  };
-
-  static bool SetPreparing() {
-    bool ret = false;
-    std::unique_lock<std::mutex> u(status_lock_);
-    if (status_ == Status::UNPREPARED) {
-      status_ = Status::PREPARING;
-      ret = true;
-    }
-    return ret;
-  }
-
-  static void SetStatus(Status status) {
-    std::unique_lock<std::mutex> u(status_lock_);
-    status_ = status;
-  }
-
-  static Status GetStatus() {
-    std::unique_lock<std::mutex> u(status_lock_);
-    return status_;
-  }
-
-  static std::unique_lock<std::shared_timed_mutex> GetWriterLock() {
-    return std::unique_lock<std::shared_timed_mutex>(lock_);
-  }
-
-  static void WriterUnLock() {
-    lock_.unlock();
-  }
-
-  static std::shared_lock<std::shared_timed_mutex> GetReaderLock() {
-    return std::shared_lock<std::shared_timed_mutex>(lock_, std::defer_lock);
-  }
-
-  static void ReaderUnLock() {
-    lock_.unlock_shared();
-  }
-
- private:
-  static inline Status status_;
-  static inline std::mutex status_lock_;
-  static inline std::shared_timed_mutex lock_;
-};
-
-}  // namespace pkgmgr_server
-
-#endif  // CACHE_FLAG_HH_
index 31039ef..dc6360f 100644 (file)
@@ -19,7 +19,7 @@
 #include <shared_mutex>
 #include <vector>
 
-#include "cache_flag.hh"
+#include "cache_provider.hh"
 #include "db_handle_provider.hh"
 #include "utils/logging.hh"
 
@@ -65,38 +65,6 @@ int AppInfoDBHandler::GetHandleFromDB(
   return ret;
 }
 
-int AppInfoDBHandler::GetHandleFromCache(
-    std::vector<std::pair<sqlite3*, uid_t>>& conn_list) {
-  bool is_write_op =
-      GetOpType() == pkgmgr_common::DBOperationType::OPERATION_TYPE_WRITE;
-  int ret = PMINFO_R_OK;
-  std::string application;
-
-  for (auto* it = filter_->list; it != nullptr; it = g_slist_next(it)) {
-    auto node = reinterpret_cast<pkgmgrinfo_node_x*>(it->data);
-    if (node->prop == E_PMINFO_APPINFO_PROP_APP_ID) {
-      application = node->value;
-      break;
-    }
-  }
-
-  std::vector<std::shared_ptr<application_x>> app_list;
-  for (auto& conn : conn_list) {
-    app_list = DBHandleProvider::GetInst(conn.second)
-                  .GetApplications(
-                      GetPID(), is_write_op, filter_, application);
-
-    handle_list_.reserve(app_list.size() + handle_list_.size());
-    std::move(std::begin(app_list), std::end(app_list),
-              std::back_inserter(handle_list_));
-  }
-
-  if (handle_list_.empty())
-    ret = PMINFO_R_ENOENT;
-
-  return ret;
-}
-
 int AppInfoDBHandler::Execute() {
   std::shared_lock<std::shared_timed_mutex> s(lock_);
   SetOpType(pkgmgr_common::DBOperationType::OPERATION_TYPE_READ);
@@ -112,16 +80,40 @@ int AppInfoDBHandler::Execute() {
     if (DBHandleProvider::GetInst(conn.second).IsWriter(GetPID()))
       is_writer = true;
   }
+
   if (is_writer)
     return GetHandleFromDB(conn_list);
 
-  if (CacheFlag::GetStatus() == CacheFlag::Status::PREPARED) {
-    auto cache_lock = CacheFlag::GetReaderLock();
-    if (cache_lock.try_lock() &&
-        CacheFlag::GetStatus() == CacheFlag::Status::PREPARED)
-      return GetHandleFromCache(conn_list);
-  }
+  CacheProvider provider(GetUID());
+  if (provider.IsPrepared() && provider.GetReadLock()) {
+    bool is_write_op =
+        GetOpType() == pkgmgr_common::DBOperationType::OPERATION_TYPE_WRITE;
+    int ret = PMINFO_R_OK;
+    std::string application;
+
+    for (auto* it = filter_->list; it != nullptr; it = g_slist_next(it)) {
+      auto node = reinterpret_cast<pkgmgrinfo_node_x*>(it->data);
+      if (node->prop == E_PMINFO_APPINFO_PROP_APP_ID) {
+        application = node->value;
+        break;
+      }
+    }
+
+    std::vector<std::shared_ptr<application_x>> app_list;
+    for (auto& conn : conn_list) {
+      app_list = CacheProvider(conn.second)
+          .GetApplications(
+              GetPID(), is_write_op, filter_, application);
+      handle_list_.reserve(app_list.size() + handle_list_.size());
+      std::move(std::begin(app_list), std::end(app_list),
+                std::back_inserter(handle_list_));
+    }
 
+    if (handle_list_.empty())
+      ret = PMINFO_R_ENOENT;
+
+    return ret;
+  }
   return GetHandleFromDB(conn_list);
 }
 
index 1e68059..aabdc99 100644 (file)
@@ -43,7 +43,6 @@ class EXPORT_API AppInfoDBHandler : public AbstractDBHandler{
 
  protected:
   int GetHandleFromDB(std::vector<std::pair<sqlite3*, uid_t>>& conn_list);
-  int GetHandleFromCache(std::vector<std::pair<sqlite3*, uid_t>>& conn_list);
   pkgmgrinfo_filter_x* filter_;
   std::vector<std::shared_ptr<application_x>> handle_list_;
   uid_t uid_;
diff --git a/src/server/database/cache.cc b/src/server/database/cache.cc
new file mode 100644 (file)
index 0000000..f26ec0a
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "cache.hh"
+
+#include <memory>
+#include <mutex>
+#include <shared_mutex>
+#include <unordered_map>
+#include <vector>
+
+#include <glib.h>
+#include <sys/types.h>
+#include <sqlite3.h>
+#include <tzplatform_config.h>
+
+#include "filter_checker_provider.hh"
+#include "utils/logging.hh"
+
+#include "pkgmgrinfo_private.h"
+#include "pkgmgrinfo_internal.h"
+#include "pkgmgrinfo_internal.hh"
+
+namespace pkgmgr_server {
+namespace database {
+
+std::unordered_map<uid_t, std::unique_ptr<Cache>> Cache::cache_map_;
+
+Cache::Cache(uid_t uid) : uid_(uid), status_(Status::UNPREPARED) {}
+
+Cache& Cache::GetInst(uid_t uid) {
+  static std::mutex singleton_lock_;
+  std::unique_lock<std::mutex> u(singleton_lock_);
+
+  auto& prov = cache_map_[uid];
+  if (prov == nullptr)
+    prov.reset(new Cache(uid));
+
+  return *prov;
+}
+
+void Cache::ReleaseAll() {
+  static std::mutex singleton_lock_;
+  std::unique_lock<std::mutex> u(singleton_lock_);
+
+  for (auto& i : cache_map_)
+    i.second->ReleaseCache();
+}
+
+bool Cache::IsCachePreparationNecessary() {
+  bool result = false;
+  std::unique_lock<std::mutex> u(status_lock_);
+  if (status_ == Status::UNPREPARED) {
+    status_ = Status::PREPARING;
+    result = true;
+  }
+
+  return result;
+}
+
+void Cache::SetPrepared() {
+  std::unique_lock<std::mutex> u(status_lock_);
+  status_ = Status::PREPARED;
+}
+
+void Cache::SetUnprepared() {
+  std::unique_lock<std::mutex> u(status_lock_);
+  status_ = Status::UNPREPARED;
+}
+
+void Cache::SetPreparing() {
+  std::unique_lock<std::mutex> u(status_lock_);
+  status_ = Status::PREPARING;
+}
+
+bool Cache::IsPrepared() {
+  std::unique_lock<std::mutex> u(status_lock_);
+  return (status_ == Status::PREPARED);
+}
+
+void Cache::ReleaseCache() {
+  auto lock = GetWriterLock();
+  SetStatus(Status::PREPARING);
+
+  pkg_map_.clear();
+  app_map_.clear();
+
+  SetStatus(Status::UNPREPARED);
+}
+
+void Cache::SetStatus(Status status) {
+  std::unique_lock<std::mutex> u(status_lock_);
+  status_ = status;
+}
+
+std::unique_lock<std::shared_timed_mutex> Cache::GetWriterLock() {
+  return std::unique_lock<std::shared_timed_mutex>(lock_);
+}
+
+void Cache::WriterUnLock() {
+  lock_.unlock();
+}
+
+std::shared_lock<std::shared_timed_mutex> Cache::GetReaderLock() {
+  return std::shared_lock<std::shared_timed_mutex>(lock_, std::defer_lock);
+}
+
+void Cache::ReaderUnLock() {
+  lock_.unlock();
+}
+
+void Cache::AddPackage(std::string package, package_x* info) {
+  auto ptr = std::shared_ptr<package_x>(info, pkgmgrinfo_basic_free_package);
+  pkg_map_[package].push_back(ptr);
+  pkg_map_[""].push_back(std::move(ptr));
+}
+
+void Cache::AddApplication(
+    std::string app, std::shared_ptr<application_x> info) {
+  app_map_[app].push_back(info);
+  app_map_[""].push_back(std::move(info));
+}
+
+int Cache::UpdateCache(sqlite3* db, pid_t pid, uid_t uid, bool write,
+    const std::string& locale) {
+  // CacheProvider should lock first and try lock before executing this func
+  pkg_map_.clear();
+  app_map_.clear();
+
+  GHashTable* list = g_hash_table_new(g_str_hash, g_str_equal);
+  if (list == nullptr) {
+    LOG(ERROR) << "Out of memory";
+    return PMINFO_R_ERROR;
+  }
+
+  auto tmp_filter = reinterpret_cast<pkgmgrinfo_filter_x*>(
+      calloc(1, sizeof(pkgmgrinfo_filter_x)));
+  if (tmp_filter == nullptr) {
+    LOG(ERROR) << "Out of memory";
+    g_hash_table_destroy(list);
+    return PMINFO_R_ERROR;
+  }
+
+  int ret = pkginfo_internal_filter_get_list(db, tmp_filter, uid_,
+                                             locale.c_str(), list);
+  if (ret != PMINFO_R_OK) {
+    g_hash_table_destroy(list);
+    free(tmp_filter);
+    return ret;
+  }
+
+  GHashTableIter iter;
+  gpointer value;
+  g_hash_table_iter_init(&iter, list);
+  while (g_hash_table_iter_next(&iter, nullptr, &value)) {
+    auto* pkg = reinterpret_cast<package_x*>(value);
+    AddPackage(pkg->package, pkg);
+  }
+  g_hash_table_destroy(list);
+
+  std::vector<std::shared_ptr<application_x>> app_list;
+  ret = pkgmgr_server::internal::appinfo_internal_filter_get_list(db,
+      tmp_filter, uid_, uid, locale.c_str(), app_list);
+  free(tmp_filter);
+  if (ret == PMINFO_R_OK) {
+    for (auto& app : app_list) {
+      app->privileges = pkg_map_[app->package].front()->privileges;
+      std::string appid = app->appid;
+      AddApplication(std::move(appid), std::move(app));
+    }
+  }
+
+  return 0;
+}
+
+std::vector<std::shared_ptr<package_x>> Cache::GetPackages(
+    pid_t pid, bool write, pkgmgrinfo_filter_x* filter,
+    const std::string& package) {
+  std::vector<std::shared_ptr<package_x>> ret;
+
+  for (auto& info : pkg_map_[package]) {
+    bool pass = true;
+    for (auto* it = filter->list; it != nullptr; it = g_slist_next(it)) {
+      auto node = reinterpret_cast<pkgmgrinfo_node_x*>(it->data);
+      auto* checker = FilterCheckerProvider::GetInst().
+          GetPkgFilterChecker(node->prop);
+      if (!checker->CheckFilter(node, info.get())) {
+        pass = false;
+        break;
+      }
+    }
+    if (pass)
+      ret.push_back(info);
+  }
+
+  return ret;
+}
+
+
+std::vector<std::shared_ptr<application_x>> Cache::GetApplications(
+    pid_t pid, bool write, pkgmgrinfo_filter_x* filter,
+    const std::string& app) {
+  /* make metadata filter map */
+  std::unordered_map<std::string, std::string> metadata_map;
+  for (auto* it = filter->list_metadata; it != nullptr; it = g_slist_next(it)) {
+    auto node = reinterpret_cast<pkgmgrinfo_metadata_node_x*>(it->data);
+    if (node->key == nullptr)
+      continue;
+
+    metadata_map[node->key] = (node->value ? node->value : "");
+  }
+
+  std::vector<std::shared_ptr<application_x>> ret;
+  for (auto& info : app_map_[app]) {
+    bool pass = true;
+    for (auto* it = filter->list; it != nullptr; it = g_slist_next(it)) {
+      auto node = reinterpret_cast<pkgmgrinfo_node_x*>(it->data);
+      auto* checker = FilterCheckerProvider::GetInst().
+          GetAppFilterChecker(node->prop);
+      if (!checker->CheckFilter(node, info.get())) {
+        pass = false;
+        break;
+      }
+    }
+    if (!pass)
+      continue;
+
+    if (!metadata_map.empty()) {
+      pass = false;
+      for (auto* it = info->metadata; it != nullptr; it = g_list_next(it)) {
+        auto* node = reinterpret_cast<metadata_x*>(it->data);
+        if (node->key != nullptr) {
+          auto metadata = metadata_map.find(node->key);
+          if (metadata != metadata_map.end() &&
+              strstr(node->value ? node->value : "",
+                  metadata->second.c_str()) != nullptr) {
+            pass = true;
+            break;
+          }
+        }
+      }
+    }
+
+    if (pass)
+      ret.push_back(info);
+  }
+
+  return ret;
+}
+
+}  // namespace database
+}  // namespace pkgmgr_server
diff --git a/src/server/database/cache.hh b/src/server/database/cache.hh
new file mode 100644 (file)
index 0000000..4c9fee9
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SERVER_CACHE_HH_
+#define SERVER_CACHE_HH_
+
+#include <sys/types.h>
+
+#include <memory>
+#include <mutex>
+#include <shared_mutex>
+#include <unordered_map>
+#include <vector>
+
+#include <sqlite3.h>
+
+#include "pkgmgrinfo_private.h"
+
+namespace pkgmgr_server {
+namespace database {
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+class EXPORT_API Cache {
+ public:
+  ~Cache() = default;
+  static Cache& GetInst(uid_t uid);
+
+  void ReleaseCache();
+  bool IsCachePreparationNecessary();
+  int UpdateCache(sqlite3* db, pid_t pid, uid_t uid, bool write,
+                  const std::string& locale);
+  std::vector<std::shared_ptr<package_x>> GetPackages(
+      pid_t pid, bool write, pkgmgrinfo_filter_x* filter,
+      const std::string& package);
+  std::vector<std::shared_ptr<application_x>> GetApplications(
+      pid_t pid, bool write, pkgmgrinfo_filter_x* filter,
+      const std::string& app);
+  void SetPrepared();
+  void SetUnprepared();
+  void SetPreparing();
+  bool IsPrepared();
+
+  std::unique_lock<std::shared_timed_mutex> GetWriterLock();
+  void WriterUnLock();
+  std::shared_lock<std::shared_timed_mutex> GetReaderLock();
+  void ReaderUnLock();
+
+  static void ReleaseAll();
+
+ private:
+  explicit Cache(uid_t uid);
+  enum class EXPORT_API Status {
+    UNPREPARED,
+    PREPARING,
+    PREPARED
+  };
+
+  void SetStatus(Status status);
+
+  void AddPackage(std::string package, package_x* info);
+  void AddApplication(std::string app, std::shared_ptr<application_x> info);
+
+  std::mutex status_lock_;
+  std::shared_timed_mutex lock_;
+  uid_t uid_;
+  Status status_;
+  std::unordered_map<std::string, std::vector<std::shared_ptr<package_x>>>
+      pkg_map_;
+  std::unordered_map<std::string, std::vector<std::shared_ptr<application_x>>>
+      app_map_;
+
+  static std::unordered_map<uid_t, std::unique_ptr<Cache>> cache_map_;
+};
+
+}  // namespace database
+}  // namespace pkgmgr_server
+
+#endif  // SERVER_CACHE_HH_
index aaf1592..a590740 100644 (file)
 #include <shared_mutex>
 #include <vector>
 
-#include "cache_flag.hh"
+#include "cache_provider.hh"
 #include "db_handle_provider.hh"
 #include "utils/logging.hh"
 
+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;
+}
+
+}  // namespace
+
 namespace pkgmgr_server {
 namespace database {
 
@@ -38,26 +58,26 @@ int CacheDBHandler::Execute() {
 
   std::vector<std::pair<sqlite3*, uid_t>> conn_list;
   if (!Connect()) {
-    CacheFlag::SetStatus(CacheFlag::Status::UNPREPARED);
+    CacheProvider(GetUID()).SetUnprepared();
     return PMINFO_R_ERROR;
   }
 
   conn_list = GetConnection();
-  auto lock = CacheFlag::GetWriterLock();
   int ret = PMINFO_R_OK;
+
   for (auto& conn : conn_list) {
-    ret = DBHandleProvider::GetInst(conn.second)
-              .UpdateCache(conn.first, GetPID(), uid_, false, GetLocale());
+    if (conn.second != ConvertUID(uid_))
+      continue;
+
+    CacheProvider provider(conn.second);
+    ret = provider.UpdateCache(conn.first, GetPID(), uid_, false, GetLocale());
     if (ret != PMINFO_R_OK) {
-      LOG(ERROR) << "Failed to update pkginfo cache : " << ret;
+      LOG(ERROR) << "Failed to update pkginfo cache for uid["
+                 << uid_ << "], ret : " << ret;
       break;
     }
   }
 
-  CacheFlag::SetStatus(ret == PMINFO_R_OK ?
-      CacheFlag::Status::PREPARED :
-      CacheFlag::Status::UNPREPARED);
-
   return ret;
 }
 
diff --git a/src/server/database/cache_provider.cc b/src/server/database/cache_provider.cc
new file mode 100644 (file)
index 0000000..25b82f7
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "cache_provider.hh"
+
+#include <memory>
+#include <mutex>
+#include <shared_mutex>
+#include <unordered_map>
+#include <vector>
+
+#include <glib.h>
+#include <sys/types.h>
+#include <sqlite3.h>
+#include <tzplatform_config.h>
+
+#include "cache.hh"
+#include "filter_checker_provider.hh"
+#include "utils/logging.hh"
+
+#include "pkgmgrinfo_private.h"
+#include "pkgmgrinfo_internal.h"
+#include "pkgmgrinfo_internal.hh"
+
+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;
+}
+
+}  // namespace
+
+namespace pkgmgr_server {
+namespace database {
+
+bool CacheProvider::IsCachePreparationNecessary() {
+  return Cache::GetInst(ConvertUID(uid_)).IsCachePreparationNecessary();
+}
+
+void CacheProvider::ReleaseCache() {
+  Cache::GetInst(ConvertUID(uid_)).ReleaseCache();
+}
+
+void CacheProvider::ReleaseAll() {
+  Cache::ReleaseAll();
+}
+
+bool CacheProvider::IsPrepared() {
+  return Cache::GetInst(ConvertUID(uid_)).IsPrepared();
+}
+
+bool CacheProvider::GetReadLock() {
+  reader_lock_ = Cache::GetInst(ConvertUID(uid_)).GetReaderLock();
+  if (reader_lock_.try_lock() && Cache::GetInst(ConvertUID(uid_)).IsPrepared())
+    return true;
+
+  reader_lock_.unlock();
+  return false;
+}
+
+void CacheProvider::SetUnprepared() {
+  Cache::GetInst(ConvertUID(uid_)).SetUnprepared();
+}
+
+int CacheProvider::UpdateCache(sqlite3* db, pid_t pid, uid_t uid, bool write,
+    const std::string& locale) {
+  auto lock = Cache::GetInst(ConvertUID(uid_)).GetWriterLock();
+
+  int ret = Cache::GetInst(ConvertUID(uid_)).UpdateCache(
+      db, pid, uid, write, locale);
+
+  if (ret == PMINFO_R_OK)
+    Cache::GetInst(ConvertUID(uid_)).SetPrepared();
+  else
+    Cache::GetInst(ConvertUID(uid_)).SetUnprepared();
+
+  return ret;
+}
+
+std::vector<std::shared_ptr<package_x>> CacheProvider::GetPackages(
+    pid_t pid, bool write, pkgmgrinfo_filter_x* filter,
+    const std::string& package) {
+  std::vector<std::shared_ptr<package_x>> ret;
+
+  uid_t target_uid = ConvertUID(uid_);
+  ret = Cache::GetInst(target_uid).GetPackages(pid, write, filter, package);
+
+  return ret;
+}
+
+std::vector<std::shared_ptr<application_x>> CacheProvider::GetApplications(
+    pid_t pid, bool write, pkgmgrinfo_filter_x* filter,
+    const std::string& app) {
+  std::vector<std::shared_ptr<application_x>> ret;
+  uid_t target_uid = ConvertUID(uid_);
+  ret = Cache::GetInst(target_uid).GetApplications(pid, write, filter, app);
+
+  return ret;
+}
+
+
+}  // namespace database
+}  // namespace pkgmgr_server
diff --git a/src/server/database/cache_provider.hh b/src/server/database/cache_provider.hh
new file mode 100644 (file)
index 0000000..d1b8db2
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SERVER_CACHE_PROVIDER_HH_
+#define SERVER_CACHE_PROVIDER_HH_
+
+#include <sys/types.h>
+
+#include <memory>
+#include <mutex>
+#include <shared_mutex>
+#include <unordered_map>
+#include <vector>
+
+#include <sqlite3.h>
+
+#include "pkgmgrinfo_private.h"
+
+namespace pkgmgr_server {
+namespace database {
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+class EXPORT_API CacheProvider {
+ public:
+  enum class EXPORT_API CacheOpResult {
+
+    PREPARED
+  };
+
+  CacheProvider(uid_t uid) : uid_(uid) {};
+  bool IsCachePreparationNecessary();
+  int UpdateCache(sqlite3* db, pid_t pid, uid_t uid,
+      bool write, const std::string& locale);
+  bool GetReadLock();
+  bool IsPrepared();
+  void ReleaseCache();
+  static void ReleaseAll();
+  void SetUnprepared();
+
+  std::vector<std::shared_ptr<package_x>> GetPackages(
+      pid_t pid, bool write, pkgmgrinfo_filter_x* filter,
+      const std::string& package);
+  std::vector<std::shared_ptr<application_x>> GetApplications(
+      pid_t pid, bool write, pkgmgrinfo_filter_x* filter,
+      const std::string& app);
+
+ private:
+  uid_t uid_;
+  std::shared_lock<std::shared_timed_mutex> reader_lock_;
+};
+
+}  // namespace database
+}  // namespace pkgmgr_server
+
+#endif  // SERVER_CACHE_PROVIDER_HH_
index 013c8e9..c8e95ee 100644 (file)
@@ -26,7 +26,7 @@
 #include <string>
 #include <vector>
 
-#include "cache_flag.hh"
+#include "cache_provider.hh"
 #include "utils/logging.hh"
 
 #include "pkgmgr-info.h"
@@ -165,8 +165,10 @@ std::vector<std::pair<std::string, uid_t>> DBHandleProvider::GetParserDBPath(
     db_path_list.emplace_back(
         std::make_pair(global_parser_memdb_path, GetGlobalUID()));
   } else {
-    if (uid_ > REGULAR_USER)
-      db_path_list.emplace_back(std::make_pair(user_parser_filedb_path_, uid_));
+    if (uid_ > REGULAR_USER) {
+      db_path_list.emplace_back(
+          std::make_pair(user_parser_filedb_path_, uid_));
+    }
 
     db_path_list.emplace_back(
         std::make_pair(global_parser_filedb_path_, GetGlobalUID()));
@@ -194,7 +196,7 @@ std::string DBHandleProvider::GetCertDBPath(pid_t pid, bool write) {
 }
 
 sqlite3* DBHandleProvider::CreateMemoryDBHandle(const std::string& filedb_path,
-                                             const std::string& memorydb_path) {
+    const std::string& memorydb_path) {
   sqlite3* memorydb = nullptr;
   sqlite3* filedb = nullptr;
   int ret = sqlite3_open_v2(memorydb_path.c_str(), &memorydb,
@@ -271,12 +273,12 @@ void DBHandleProvider::UnsetMemoryMode(pid_t pid) {
   is_user_memdb_set_ = false;
   is_global_memdb_set_ = false;
 
-  auto lock = CacheFlag::GetWriterLock();
-  CacheFlag::SetStatus(CacheFlag::Status::PREPARING);
+  CacheProvider provider(uid_);
+  provider.ReleaseCache();
+
+  if (ConvertUID(uid_) != GetGlobalUID())
+    CacheProvider(GetGlobalUID()).ReleaseCache();
 
-  pkg_map_.clear();
-  app_map_.clear();
-  CacheFlag::SetStatus(CacheFlag::Status::UNPREPARED);
   LOG(DEBUG) << "Set Memory mode : File";
 }
 
@@ -294,168 +296,11 @@ bool DBHandleProvider::IsMemoryDBActive(pid_t pid, bool write) {
   return true;
 }
 
-void DBHandleProvider::TrimCache() {
-  std::unique_lock<std::recursive_mutex> u(lock_);
-  if (!released_)
-    ReleaseCache();
-}
-
-void DBHandleProvider::ReleaseCache() {
-  auto lock = CacheFlag::GetWriterLock();
-  CacheFlag::SetStatus(CacheFlag::Status::PREPARING);
-
-  app_map_.clear();
-  pkg_map_.clear();
-  CacheFlag::SetStatus(CacheFlag::Status::UNPREPARED);
-
-  released_ = true;
-}
-
 bool DBHandleProvider::IsWriter(pid_t pid) {
   std::unique_lock<std::mutex> u(pid_list_lock_);
   return writer_pid_list_.find(pid) != writer_pid_list_.end();
 }
 
-int DBHandleProvider::UpdateCache(sqlite3* db, pid_t pid, uid_t uid, bool write,
-    const std::string& locale) {
-  pkg_map_.clear();
-  app_map_.clear();
-
-  GHashTable* list = g_hash_table_new(g_str_hash, g_str_equal);
-  if (list == nullptr) {
-    LOG(ERROR) << "Out of memory";
-    return PMINFO_R_ERROR;
-  }
-
-  auto tmp_filter = reinterpret_cast<pkgmgrinfo_filter_x*>(
-      calloc(1, sizeof(pkgmgrinfo_filter_x)));
-  if (tmp_filter == nullptr) {
-    LOG(ERROR) << "Out of memory";
-    g_hash_table_destroy(list);
-    return PMINFO_R_ERROR;
-  }
-
-  int ret = pkginfo_internal_filter_get_list(db, tmp_filter, uid_,
-                                             locale.c_str(), list);
-  if (ret == PMINFO_R_OK) {
-    GHashTableIter iter;
-    gpointer value;
-    g_hash_table_iter_init(&iter, list);
-    while (g_hash_table_iter_next(&iter, nullptr, &value)) {
-      auto* pkg = reinterpret_cast<package_x*>(value);
-      std::string pkgid = pkg->package;
-      AddPackage(std::move(pkgid), pkg);
-    }
-  }
-
-  g_hash_table_destroy(list);
-  if (ret == PMINFO_R_ERROR) {
-    free(tmp_filter);
-    return ret;
-  }
-
-  std::vector<std::shared_ptr<application_x>> app_list;
-  ret = pkgmgr_server::internal::appinfo_internal_filter_get_list(db,
-      tmp_filter, uid_, uid, locale.c_str(), app_list);
-  free(tmp_filter);
-  if (ret == PMINFO_R_OK) {
-    for (auto& app : app_list) {
-      app->privileges = pkg_map_[app->package].front()->privileges;
-      std::string appid = app->appid;
-      AddApplication(std::move(appid), std::move(app));
-    }
-  }
-  released_ = false;
-
-  return ret;
-}
-
-std::vector<std::shared_ptr<package_x>> DBHandleProvider::GetPackages(
-    pid_t pid, bool write, pkgmgrinfo_filter_x* filter,
-    const std::string& package) {
-  std::vector<std::shared_ptr<package_x>> ret;
-  for (auto& info : pkg_map_[package]) {
-    bool pass = true;
-    for (auto* it = filter->list; it != nullptr; it = g_slist_next(it)) {
-      auto node = reinterpret_cast<pkgmgrinfo_node_x*>(it->data);
-      auto* checker = FilterCheckerProvider::GetInst().
-          GetPkgFilterChecker(node->prop);
-      if (!checker->CheckFilter(node, info.get())) {
-        pass = false;
-        break;
-      }
-    }
-    if (pass)
-      ret.push_back(info);
-  }
-
-  return ret;
-}
-
-void DBHandleProvider::AddPackage(std::string package, package_x* info) {
-  auto ptr = std::shared_ptr<package_x>(info, pkgmgrinfo_basic_free_package);
-  pkg_map_[package].push_back(ptr);
-  pkg_map_[""].push_back(std::move(ptr));
-}
-
-std::vector<std::shared_ptr<application_x>> DBHandleProvider::GetApplications(
-    pid_t pid, bool write, pkgmgrinfo_filter_x* filter,
-    const std::string& app) {
-  /* make metadata filter map */
-  std::unordered_map<std::string, std::string> metadata_map;
-  for (auto* it = filter->list_metadata; it != nullptr; it = g_slist_next(it)) {
-    auto node = reinterpret_cast<pkgmgrinfo_metadata_node_x*>(it->data);
-    if (node->key == nullptr)
-      continue;
-
-    metadata_map[node->key] = (node->value ? node->value : "");
-  }
-
-  std::vector<std::shared_ptr<application_x>> ret;
-  for (auto& info : app_map_[app]) {
-    bool pass = true;
-    for (auto* it = filter->list; it != nullptr; it = g_slist_next(it)) {
-      auto node = reinterpret_cast<pkgmgrinfo_node_x*>(it->data);
-      auto* checker = FilterCheckerProvider::GetInst().
-          GetAppFilterChecker(node->prop);
-      if (!checker->CheckFilter(node, info.get())) {
-        pass = false;
-        break;
-      }
-    }
-    if (!pass)
-      continue;
-
-    if (!metadata_map.empty()) {
-      pass = false;
-      for (auto* it = info->metadata; it != nullptr; it = g_list_next(it)) {
-        auto* node = reinterpret_cast<metadata_x*>(it->data);
-        if (node->key != nullptr) {
-          auto metadata = metadata_map.find(node->key);
-          if (metadata == metadata_map.end())
-            continue;
-
-          if (metadata->second.empty() ||
-              strcmp(node->value ? node->value : "",
-                  metadata->second.c_str()) == 0) {
-            pass = true;
-            break;
-          }
-        }
-      }
-    }
-
-    if (pass)
-      ret.push_back(info);
-  }
-  return ret;
-}
-
-void DBHandleProvider::AddApplication(std::string app, std::shared_ptr<application_x> info) {
-  app_map_[app].push_back(info);
-  app_map_[""].push_back(std::move(info));
-}
-
 void DBHandleProvider::InsertPID(pid_t pid) {
   std::unique_lock<std::mutex> u(pid_list_lock_);
 
index 7795732..16dc89c 100644 (file)
@@ -50,15 +50,6 @@ class EXPORT_API DBHandleProvider {
   std::string GetCertDBPath(int pid, bool write);
   void SetMemoryMode(pid_t pid);
   void UnsetMemoryMode(pid_t pid);
-  int UpdateCache(sqlite3* db, pid_t pid, uid_t uid, bool write,
-                  const std::string& locale);
-  std::vector<std::shared_ptr<package_x>> GetPackages(
-      pid_t pid, bool write, pkgmgrinfo_filter_x* filter,
-      const std::string& package);
-  std::vector<std::shared_ptr<application_x>> GetApplications(
-      pid_t pid, bool write, pkgmgrinfo_filter_x* filter,
-      const std::string& app);
-  void TrimCache();
   bool IsWriter(pid_t pid);
 
  private:
@@ -66,9 +57,6 @@ class EXPORT_API DBHandleProvider {
   sqlite3* CreateMemoryDBHandle(const std::string& filedb_path,
                              const std::string& memorydb_path);
   bool IsMemoryDBActive(pid_t pid, bool write);
-  void ReleaseCache();
-  void AddPackage(std::string package, package_x* info);
-  void AddApplication(std::string app, std::shared_ptr<application_x> info);
   void InsertPID(pid_t pid);
   bool ErasePID(pid_t pid);
 
@@ -92,11 +80,6 @@ class EXPORT_API DBHandleProvider {
       parser_memdb_handle_;
   std::string user_parser_memdb_path_;
   std::string user_parser_filedb_path_;
-  bool released_ = true;
-  std::unordered_map<std::string, std::vector<std::shared_ptr<package_x>>>
-      pkg_map_;
-  std::unordered_map<std::string, std::vector<std::shared_ptr<application_x>>>
-      app_map_;
 };
 
 }  // namespace database
index 0e67de7..b4c7c4f 100644 (file)
@@ -19,7 +19,7 @@
 #include <shared_mutex>
 #include <vector>
 
-#include "cache_flag.hh"
+#include "cache_provider.hh"
 #include "db_handle_provider.hh"
 
 #include "pkgmgrinfo_debug.h"
@@ -80,35 +80,6 @@ int PkgGetDBHandler::GetHandleFromDB(
   return ret;
 }
 
-int PkgGetDBHandler::GetHandleFromCache(
-    std::vector<std::pair<sqlite3*, uid_t>>& conn_list) {
-  int ret = PMINFO_R_OK;
-  std::string package;
-
-  for (auto* it = filter_->list; it != nullptr; it = g_slist_next(it)) {
-    auto node = reinterpret_cast<pkgmgrinfo_node_x*>(it->data);
-    if (node->prop == E_PMINFO_PKGINFO_PROP_PACKAGE_ID) {
-      package = node->value;
-      break;
-    }
-  }
-
-  std::vector<std::shared_ptr<package_x>> pkg_list;
-  for (auto& conn : conn_list) {
-    pkg_list = DBHandleProvider::GetInst(conn.second)
-                        .GetPackages(GetPID(), false, filter_, package);
-
-    handle_list_.reserve(pkg_list.size() + handle_list_.size());
-    std::move(std::begin(pkg_list), std::end(pkg_list),
-              std::back_inserter(handle_list_));
-  }
-
-  if (handle_list_.empty())
-    return PMINFO_R_ENOENT;
-
-  return ret;
-}
-
 int PkgGetDBHandler::Execute() {
   std::shared_lock<std::shared_timed_mutex> s(lock_);
   SetOpType(pkgmgr_common::DBOperationType::OPERATION_TYPE_READ);
@@ -128,11 +99,32 @@ int PkgGetDBHandler::Execute() {
   if (is_writer)
     return GetHandleFromDB(conn_list);
 
-  if (CacheFlag::GetStatus() == CacheFlag::Status::PREPARED) {
-    auto cache_lock = CacheFlag::GetReaderLock();
-    if (cache_lock.try_lock() &&
-        CacheFlag::GetStatus() == CacheFlag::Status::PREPARED)
-      return GetHandleFromCache(conn_list);
+  CacheProvider provider(GetUID());
+  if (provider.IsPrepared() && provider.GetReadLock()) {
+    int ret = PMINFO_R_OK;
+    std::string package;
+
+    for (auto* it = filter_->list; it != nullptr; it = g_slist_next(it)) {
+      auto node = reinterpret_cast<pkgmgrinfo_node_x*>(it->data);
+      if (node->prop == E_PMINFO_PKGINFO_PROP_PACKAGE_ID) {
+        package = node->value;
+        break;
+      }
+    }
+
+    std::vector<std::shared_ptr<package_x>> pkg_list;
+    for (auto& conn : conn_list) {
+      pkg_list = CacheProvider(conn.second)
+                          .GetPackages(GetPID(), false, filter_, package);
+      handle_list_.reserve(pkg_list.size() + handle_list_.size());
+      std::move(std::begin(pkg_list), std::end(pkg_list),
+                std::back_inserter(handle_list_));
+    }
+
+    if (handle_list_.empty())
+      return PMINFO_R_ENOENT;
+
+    return ret;
   }
 
   return GetHandleFromDB(conn_list);
index ba16187..e34c099 100644 (file)
@@ -42,7 +42,6 @@ class EXPORT_API PkgGetDBHandler : public AbstractDBHandler {
 
  protected:
   int GetHandleFromDB(std::vector<std::pair<sqlite3*, uid_t>>& conn_list);
-  int GetHandleFromCache(std::vector<std::pair<sqlite3*, uid_t>>& conn_list);
   pkgmgrinfo_filter_x* filter_ = nullptr;
   std::vector<std::shared_ptr<package_x>> handle_list_;
   uid_t uid_;
index d450751..78d9c8c 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "utils/logging.hh"
 #include "db_handle_provider.hh"
+#include "cache_provider.hh"
 
 #include "pkgmgrinfo_debug.h"
 #include "pkgmgrinfo_internal.h"
@@ -299,7 +300,8 @@ int QueryHandler::Execute() {
       }
     }
     __free_query_list(queries, args_list);
-    database::DBHandleProvider::GetInst(GetUID()).TrimCache();
+    CacheProvider(GetUID()).ReleaseCache();
+
     return ret;
   }
   return ret;
index 4f00260..d93b7c9 100644 (file)
@@ -19,5 +19,13 @@ pid_t AbstractRequestHandler::GetPID() {
   return pid_;
 }
 
+void AbstractRequestHandler::SetUID(uid_t uid) {
+  uid_ = uid;
+}
+
+uid_t AbstractRequestHandler::GetUID() {
+  return uid_;
+}
+
 }  // namespace request_handler
 }  // namespace pkgmgr_server
index 8285e80..ea82ef0 100644 (file)
@@ -27,12 +27,15 @@ class EXPORT_API AbstractRequestHandler {
   virtual std::vector<uint8_t> ExtractResult() = 0;
 
   void SetPID(pid_t pid);
+  void SetUID(uid_t uid);
 
  protected:
   pid_t GetPID();
+  uid_t GetUID();
 
  private:
   pid_t pid_;
+  uid_t uid_;
 };
 
 }  // namespace request_handler
index 4e60054..1c2c071 100644 (file)
@@ -15,8 +15,7 @@ namespace request_handler {
 
 bool CreateCacheRequestHandler::HandleRequest(unsigned char* data, int size,
                                             const std::string& locale) {
-  // TODO(ilho159.kim) need to get logined user id
-  psd::CacheDBHandler db(5001, GetPID());
+  psd::CacheDBHandler db(GetUID(), GetPID());
   db.SetLocale(locale);
 
   int ret = db.Execute();
index 52e8211..9686d96 100644 (file)
@@ -24,7 +24,7 @@
 #include <unordered_map>
 #include <vector>
 
-#include "cache_flag.hh"
+#include "cache_provider.hh"
 #include "create_cache_request.hh"
 #include "cynara_checker.hh"
 #include "pkg_request.hh"
 #endif
 #define LOG_TAG "PKGMGR_INFO"
 
+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;
+}
+
+}  // namespace
+
 namespace pkgmgr_server {
 namespace {
 
@@ -94,16 +114,27 @@ int Runner::OnReceiveRequest(int fd, GIOCondition cond, void* user_data) {
   }
 
   auto req = std::make_shared<PkgRequest>(client_fd);
-  if (req->ReceiveData()) {
-    pkgmgr_common::ReqType type = req->GetRequestType();
-    if (CacheFlag::SetPreparing()) {
+  if (!req->ReceiveData())
+    return G_SOURCE_CONTINUE;
+
+  pkgmgr_server::database::CacheProvider provider(req->GetSenderUID());
+  if (provider.IsCachePreparationNecessary()) {
+    runner->QueueRequest(
+        std::make_shared<CreateCacheRequest>(req->GetSenderUID()));
+  }
+
+  if (ConvertUID(req->GetSenderUID()) != GetGlobalUID()) {
+    pkgmgr_server::database::CacheProvider global_provider(GetGlobalUID());
+    if (global_provider.IsCachePreparationNecessary()) {
       runner->QueueRequest(
-          std::make_shared<CreateCacheRequest>(req->GetSenderUID()));
+          std::make_shared<CreateCacheRequest>(GetGlobalUID()));
     }
-    std::vector<std::string>&& privileges = GetPrivileges(type);
-    CynaraChecker::GetInst().CheckPrivilege(runner, req, privileges);
   }
 
+  pkgmgr_common::ReqType type = req->GetRequestType();
+  std::vector<std::string>&& privileges = GetPrivileges(type);
+  CynaraChecker::GetInst().CheckPrivilege(runner, req, privileges);
+
   return G_SOURCE_CONTINUE;
 }
 
index 08f2929..87287e0 100644 (file)
@@ -20,6 +20,7 @@
 #include <malloc.h>
 
 #include "abstract_parcelable.hh"
+#include "cache_provider.hh"
 #include "command_request_handler.hh"
 #include "create_cache_request_handler.hh"
 #include "create_db_request_handler.hh"
@@ -120,6 +121,7 @@ void WorkerThread::Run() {
 
     try {
       handler[type]->SetPID(req->GetSenderPID());
+      handler[type]->SetUID(req->GetSenderUID());
       if (!handler[type]->HandleRequest(req->GetData(), req->GetSize(),
                                         locale_.GetObject()))
         LOG(ERROR) << "Failed to handle request";
@@ -165,9 +167,7 @@ gboolean WorkerThread::TrimMemory(void* data) {
     database::DBHandleProvider::
         GetInst(getuid()).UnsetMemoryMode(getpid());
 
-  database::DBHandleProvider::
-        GetInst(getuid()).TrimCache();
-
+  database::CacheProvider::ReleaseAll();
   return false;
 }