Optimaze of cases that read multiple data in shm 78/324278/3
authorIlho Kim <ilho159.kim@samsung.com>
Thu, 15 May 2025 06:44:06 +0000 (15:44 +0900)
committerIlho Kim <ilho159.kim@samsung.com>
Thu, 15 May 2025 09:56:31 +0000 (18:56 +0900)
When reader read multiple handles, memory copy was performed as many as
the number of handles.
This patch makes handles from the memory buffer that copies the entire
shared memory

Change-Id: I9a04fadde51cd39142e1ccc36b1f643e42d6e475
Signed-off-by: Ilho Kim <ilho159.kim@samsung.com>
src/common/shared_memory/shm_app_reader.cc
src/common/shared_memory/shm_app_reader.hh
src/common/shared_memory/shm_pkg_reader.cc
src/common/shared_memory/shm_pkg_reader.hh
src/common/shared_memory/shm_reader.cc
src/common/shared_memory/shm_reader.hh

index 045bdbe9604a73be7a012e84d87637fa34a3965e..72027c77da9d71abad04b404d87323bae0146abf 100644 (file)
@@ -63,15 +63,9 @@ namespace shared_memory {
 
 static const std::string APP_SHM_PREFIX = ".pkgmgr_info_app_";
 
-inline bool CheckPrivilegeFilters(const char* pkgid, uid_t uid,
+inline bool CheckPrivilegeFilters(const PkgInfoHandle& p_handle,
     const std::unordered_set<std::string>& privilege_filters) {
-  ShmPkgReader pkg_reader(uid);
-
-  auto pkg_info = pkg_reader.GetHandle(pkgid);
-  if (!pkg_info)
-    return false;
-
-  for (const auto priv : pkg_info->GetPrivileges()) {
+  for (const auto priv : p_handle.GetPrivileges()) {
     if (priv.Value() != nullptr && privilege_filters.count(priv.Value()))
       return true;
   }
@@ -119,18 +113,73 @@ int ShmAppReader::GetHandles(pkgmgrinfo_filter_x* filter,
       }
     }
   } else {
-    for (auto& reader : readers_) {
-      ShmError result;
-      auto handles = reader->GetHandles(&result);
-      if (!handles && result != ShmError::NONE)
-        return PMINFO_R_ERROR;
+    if (!filter_checker.HasPrivilegeFilter()) {
+      for (auto& reader : readers_) {
+        ShmError result;
+        auto handles = reader->GetHandles(&result);
+        if (!handles && result != ShmError::NONE)
+          return PMINFO_R_ERROR;
 
-      if (!handles)
-        continue;
+        if (!handles)
+          continue;
 
-      for (auto& handle : *handles)
-        if (filter_checker.Check(handle))
-          list.emplace(handle.GetAppId(), std::move(handle));
+        for (const auto& [_ , handle] : handles->GetMap())
+          if (filter_checker.Check(handle))
+            list.emplace(handle.GetAppId(), handle.Clone());
+      }
+    } else {
+      std::vector<ShmReader<PkgInfoHandle>*> pkg_readers;
+      pkg_readers.emplace_back(
+          ShmPkgReader::ShmPkgReaderProvider::GetReader(uid_));
+      if (uid_ > REGULAR_USER)
+        pkg_readers.emplace_back(
+              ShmPkgReader::ShmPkgReaderProvider::GetReader(GLOBAL_USER));
+
+      auto app_it = readers_.begin();
+      auto pkg_it = pkg_readers.begin();
+
+      while (app_it != readers_.end() && pkg_it != pkg_readers.end()) {
+        auto pkg_lock = (*pkg_it)->GetLock();
+        auto app_lock = (*app_it)->GetLock();
+
+        if (!pkg_lock || !app_lock) {
+          LOGW("Failed to get lock");
+          return PMINFO_R_ERROR;
+        }
+
+        ShmError result;
+        auto app_handles = (*app_it)->GetHandles(&result);
+        if (!app_handles && result != ShmError::NONE)
+          return PMINFO_R_ERROR;
+
+        if (!app_handles) {
+          app_it++;
+          pkg_it++;
+          continue;
+        }
+
+        auto pkg_handles = (*pkg_it)->GetHandles(&result);
+        if (!pkg_handles && result != ShmError::NONE)
+          return PMINFO_R_ERROR;
+
+        pkg_lock->Unlock();
+        app_lock->Unlock();
+
+
+        const auto& pkg_maps = pkg_handles->GetMap();
+        for (const auto& [_ , a_handle] : app_handles->GetMap()) {
+          auto pkg_it = pkg_maps.find(a_handle.GetPackage());
+          if (pkg_it == pkg_maps.end())
+            continue;
+
+          if (filter_checker.Check(a_handle) &&
+              filter_checker.CheckPrivilege(pkg_it->second))
+            list.emplace(a_handle.GetAppId(), a_handle.Clone());
+        }
+
+        app_it++;
+        pkg_it++;
+      }
     }
   }
 
@@ -193,10 +242,6 @@ bool ShmAppReader::FilterChecker::Check(const AppInfoHandle& handle) {
   if (!metadata_map_.empty() && !CheckMetadataFilter(&handle, metadata_map_))
     return false;
 
-  if (!privilege_filters_.empty() &&
-      !CheckPrivilegeFilters(handle.GetPackage(), uid_, privilege_filters_))
-    return false;
-
   for (auto [checker, value] : filter_checker_)
     if (!checker->CheckFilter(value, &handle))
       return false;
@@ -204,10 +249,22 @@ bool ShmAppReader::FilterChecker::Check(const AppInfoHandle& handle) {
   return true;
 }
 
+bool ShmAppReader::FilterChecker::CheckPrivilege(
+    const PkgInfoHandle& p_handle) {
+  if (!CheckPrivilegeFilters(p_handle, privilege_filters_))
+    return false;
+
+  return true;
+}
+
 const char* ShmAppReader::FilterChecker::AppIdFilterValue() {
   return appid_filter_;
 }
 
+bool ShmAppReader::FilterChecker::HasPrivilegeFilter() {
+  return !privilege_filters_.empty();
+}
+
 ShmReader<AppInfoHandle>*
     ShmAppReader::ShmAppReaderProvider::GetReader(uid_t uid) {
   static std::shared_mutex lock_;
index 58d023a21464dab1a50e6fdfb88a73437f1388ac..38d811aef8a8406ab4b21ee6ba737e6f8f9efff6 100644 (file)
@@ -32,7 +32,9 @@ class EXPORT_API ShmAppReader {
     FilterChecker(uid_t uid);
     bool Init(pkgmgrinfo_filter_x* filter);
     bool Check(const AppInfoHandle& handle);
+    bool CheckPrivilege(const PkgInfoHandle& p_handle);
     const char* AppIdFilterValue();
+    bool HasPrivilegeFilter();
 
    private:
     uid_t uid_;
index 4b9645e910f35060791573496090d7b6e374d55b..cacfa557dda0d21bb807e95e0467181c4e8b468c 100644 (file)
@@ -132,9 +132,9 @@ int ShmPkgReader::GetHandles(pkgmgrinfo_filter_x* filter,
       if (!handles)
         continue;
 
-      for (auto& handle : *handles)
+      for (const auto& [_ , handle] : handles->GetMap())
         if (filter_checker.Check(handle))
-          list.emplace(handle.GetPackage(), std::move(handle));
+          list.emplace(handle.GetPackage(), handle.Clone());
     }
   }
 
index cde723499d366015e9cdbc59023c57b4c1033bf5..81b2b12cd9377e6b52f379c3acc6c928a363f1b6 100644 (file)
@@ -19,6 +19,17 @@ namespace shared_memory {
 
 class EXPORT_API ShmPkgReader {
  public:
+  class EXPORT_API ShmPkgReaderProvider {
+   public:
+    ShmPkgReaderProvider() = delete;
+
+    static ShmReader<PkgInfoHandle>* GetReader(uid_t uid);
+
+   private:
+    static inline std::unordered_map<uid_t,
+        ShmReader<PkgInfoHandle>*> readers_map_;
+  };
+
   ShmPkgReader(uid_t uid);
 
   int GetHandles(pkgmgrinfo_filter_x* filter,
@@ -38,17 +49,6 @@ class EXPORT_API ShmPkgReader {
     std::vector<std::pair<IPkgFilterChecker*, const char*>> filter_checker_;
   };
 
-  class EXPORT_API ShmPkgReaderProvider {
-   public:
-    ShmPkgReaderProvider() = delete;
-
-    static ShmReader<PkgInfoHandle>* GetReader(uid_t uid);
-
-   private:
-    static inline std::unordered_map<uid_t,
-        ShmReader<PkgInfoHandle>*> readers_map_;
-  };
-
  private:
   std::vector<ShmReader<PkgInfoHandle>*> readers_;
 };
index a25e23219a927ecebd5b0e9f1333f1abfedf5f68..bfbd4a2c49f10ca01a32e8a6d563e373984db29d 100644 (file)
@@ -126,7 +126,7 @@ std::optional<ShmLockGuard> ShmReader<T>::Load(ShmError* result,
 }
 
 template<typename T>
-std::optional<std::vector<T>> ShmReader<T>::GetHandles(ShmError* result) {
+std::optional<typename ShmReader<T>::HandleCollection> ShmReader<T>::GetHandles(ShmError* result) {
   std::shared_lock<std::shared_mutex> s(lock_);
   auto lock = Load(result, s);
   if (!lock)
@@ -160,7 +160,18 @@ std::optional<T> ShmReader<T>::GetHandle(const char* key, ShmError* result) {
 }
 
 template<typename T>
-std::optional<std::vector<T>> ShmReader<T>::ReadHandles(ShmError* result) {
+std::optional<ShmLockGuard> ShmReader<T>::GetLock() {
+  std::shared_lock<std::shared_mutex> s(lock_);
+  ShmError result;
+  auto lock = Load(&result, s);
+  if (!lock)
+    return std::nullopt;
+
+  return lock;
+}
+
+template<typename T>
+std::optional<typename ShmReader<T>::HandleCollection> ShmReader<T>::ReadHandles(ShmError* result) {
   if (!result) {
     LOGE("Invalid parameter");
     return std::nullopt;
@@ -170,19 +181,24 @@ std::optional<std::vector<T>> ShmReader<T>::ReadHandles(ShmError* result) {
 
   if (index_mapper_.GetMemSize() == 0) {
     LOGD("Empty Shm Data");
-    return std::vector<T>{};
+    ShmReader<T>::HandleCollection({}, {});
   }
 
-  std::vector<T> handles;
-  uint8_t* ptr = handle_mapper_.GetPtr();
+  std::map<std::string, T> handles;
+  std::vector<uint8_t> data(
+      handle_mapper_.GetPtr(),
+      handle_mapper_.GetPtr() + handle_mapper_.GetMemSize());
+  uint8_t* ptr = data.data();
   auto index_ptr = (HandleMappingData*)index_mapper_.GetPtr();
   auto end_ptr =
       (HandleMappingData*)(index_mapper_.GetPtr() + index_mapper_.GetMemSize());
-  for (; index_ptr != end_ptr; index_ptr++)
-    handles.emplace_back(std::make_unique<tizen_base::Parcel>(
-        ptr + index_ptr->index, index_ptr->len, true));
+  for (; index_ptr != end_ptr; index_ptr++) {
+    T handle(std::make_unique<tizen_base::Parcel>(
+        ptr + index_ptr->index, index_ptr->len, false, false));
+    handles.emplace(handle.GetKey(), std::move(handle));
+  }
 
-  return handles;
+  return ShmReader<T>::HandleCollection(std::move(data), std::move(handles));
 }
 
 template<typename T>
index f34f93d5fc0b07fc4655706f5fb3e826c0dc4b7e..dc1bc5b2ad615514c83c889cd635ae1049b60ca6 100644 (file)
@@ -5,6 +5,7 @@
 #include <optional>
 #include <shared_mutex>
 #include <vector>
+#include <map>
 
 #include "pkgmgr_info_handle.hh"
 #include "pkgmgrinfo_private.h"
@@ -20,18 +21,34 @@ namespace shared_memory {
 template<typename T>
 class EXPORT_API ShmReader {
  public:
+  class HandleCollection {
+   public:
+    HandleCollection(std::vector<uint8_t> data,
+        std::map<std::string, T> handles)
+            : data_(std::move(data)), handles_(std::move(handles)) {}
+
+    const std::map<std::string, T>& GetMap() {
+      return handles_;
+    }
+
+   private:
+    std::vector<uint8_t> data_;
+    std::map<std::string, T> handles_;
+  };
+
   ShmReader(std::string base_name) :
       base_name_(std::move(base_name)),
       config_handler_(base_name_ + "_config"),
       handle_mapper_(base_name_ + "_handle"),
       index_mapper_(base_name_ + "_indexs") {}
-  std::optional<std::vector<T>> GetHandles(ShmError* result);
+  std::optional<HandleCollection> GetHandles(ShmError* result);
   std::optional<T> GetHandle(const char* key, ShmError* result);
+  std::optional<ShmLockGuard> GetLock();
 
  private:
   std::optional<ShmLockGuard> Load(ShmError* result,
       std::shared_lock<std::shared_mutex>& s);
-  std::optional<std::vector<T>> ReadHandles(ShmError* result);
+  std::optional<HandleCollection> ReadHandles(ShmError* result);
   std::optional<T> ReadHandle(uint32_t index, uint32_t len);
   HandleMappingData* FindIndex(const char* key, ShmError* result);