"QUERY",
"COMMAND",
"CREATE_DB",
+ "CREATE_CACHE",
"ERROR_REQ_TYPE"
};
QUERY,
COMMAND,
CREATE_DB,
+ CREATE_CACHE,
MAX
};
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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.
+ */
+
+#include "create_cache_request.hh"
+
+#include <sys/types.h>
+#include <unistd.h>
+
+namespace pkgmgr_server {
+
+unsigned char* CreateCacheRequest::GetData() {
+ return nullptr;
+}
+
+int CreateCacheRequest::GetSize() {
+ return 0;
+}
+
+pid_t CreateCacheRequest::GetSenderPID() {
+ return getpid();
+}
+
+uid_t CreateCacheRequest::GetSenderUID() {
+ return uid_;
+}
+
+pkgmgr_common::ReqType CreateCacheRequest::GetRequestType() {
+ return pkgmgr_common::ReqType::CREATE_CACHE;
+}
+
+bool CreateCacheRequest::SendData(unsigned char* data, int size) {
+ return true;
+}
+
+} // namespace pkgmgr_server
--- /dev/null
+/*
+ * 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 SERVER_CREATE_CACHE_REQUEST_HH_
+#define SERVER_CREATE_CACHE_REQUEST_HH_
+
+#include <sys/types.h>
+
+#include "pkg_request.hh"
+#include "request_type.hh"
+
+namespace pkgmgr_server {
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+class EXPORT_API CreateCacheRequest : public PkgRequest {
+ public:
+ CreateCacheRequest(uid_t uid) : uid_(uid) {}
+ unsigned char* GetData() override;
+ int GetSize() override;
+ pid_t GetSenderPID() override;
+ uid_t GetSenderUID() override;
+ pkgmgr_common::ReqType GetRequestType() override;
+ bool SendData(unsigned char* data, int size) override;
+
+ private:
+ uid_t uid_;
+};
+
+} // namespace pkgmgr_server
+
+#endif // SERVER_CREATE_CACHE_REQUEST_HH_
static std::shared_timed_mutex lock_;
private:
-
pkgmgr_common::DBType db_type_;
pkgmgr_common::DBOperationType op_type_;
uid_t uid_;
+++ /dev/null
-/*
- * 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.
- */
-
-#include "appinfo_cache_db_handler.hh"
-
-#include <shared_mutex>
-#include <vector>
-
-#include "db_handle_provider.hh"
-#include "pkgmgrinfo_basic.h"
-#include "pkgmgrinfo_debug.h"
-#include "utils/logging.hh"
-
-namespace pkgmgr_server {
-namespace database {
-
-AppInfoCacheDBHandler::AppInfoCacheDBHandler(uid_t uid, int pid)
- : AppInfoDBHandler(uid, pid) {}
-
-int AppInfoCacheDBHandler::Execute() {
- std::shared_lock<std::shared_timed_mutex> s(lock_);
- SetOpType(pkgmgr_common::DBOperationType::OPERATION_TYPE_READ);
- SetDBType(pkgmgr_common::DBType::DB_TYPE_FILE_PKGDB);
- bool write =
- GetOpType() == pkgmgr_common::DBOperationType::OPERATION_TYPE_WRITE;
-
- std::vector<std::pair<sqlite3*, uid_t>> conn_list;
- if (!Connect())
- return PMINFO_R_ERROR;
-
- conn_list = GetConnection();
-
- 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) {
- ret = DBHandleProvider::GetInst(conn.second)
- .UpdateCache(conn.first, GetPID(), uid_, write, GetLocale());
- if (ret != PMINFO_R_OK) {
- LOG(DEBUG) << "Failed to update appinfo cache: " << ret;
- break;
- }
-
- app_list = DBHandleProvider::GetInst(conn.second)
- .GetApplications(GetPID(), write, 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;
-}
-
-} // namespace database
-} // namespace pkgmgr_server
+++ /dev/null
-/*
- * 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 APPINFO_CACHE_DB_HANDLER_HH_
-#define APPINFO_CACHE_DB_HANDLER_HH_
-
-#include <vector>
-
-#include <sys/types.h>
-
-#include "appinfo_db_handler.hh"
-#include "pkgmgrinfo_basic.h"
-#include "pkgmgrinfo_private.h"
-
-namespace pkgmgr_server {
-namespace database {
-
-#ifndef EXPORT_API
-#define EXPORT_API __attribute__((visibility("default")))
-#endif
-
-class EXPORT_API AppInfoCacheDBHandler : public AppInfoDBHandler {
- public:
- AppInfoCacheDBHandler(uid_t uid, int pid);
- int Execute() override;
-};
-
-} // namespace database
-} // namespace pkgmgr_server
-
-#endif // APPINFO_CACHE_DB_HANDLER_HH_
#include <shared_mutex>
#include <vector>
+#include "cache_flag.hh"
+#include "db_handle_provider.hh"
#include "utils/logging.hh"
#include "pkgmgrinfo_basic.h"
-#include "pkgmgrinfo_debug.h"
#include "pkgmgrinfo_internal.h"
namespace {
filter_ = filter;
}
-int AppInfoDBHandler::Execute() {
- std::shared_lock<std::shared_timed_mutex> s(lock_);
- SetOpType(pkgmgr_common::DBOperationType::OPERATION_TYPE_READ);
- SetDBType(pkgmgr_common::DBType::DB_TYPE_FILE_PKGDB);
-
- if (!Connect())
- return PMINFO_R_ERROR;
-
+int AppInfoDBHandler::GetHandleFromDB(
+ std::vector<std::pair<sqlite3*, uid_t>>& conn_list) {
GHashTable* list =
g_hash_table_new_full(g_str_hash, g_str_equal, nullptr, nullptr);
- std::vector<std::pair<sqlite3*, uid_t>> conn_list = GetConnection();
int ret = PMINFO_R_OK;
for (auto& conn : conn_list) {
ret = appinfo_internal_filter_get_list(conn.first, filter_, conn.second,
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);
+ SetDBType(pkgmgr_common::DBType::DB_TYPE_FILE_PKGDB);
+
+ if (!Connect())
+ return PMINFO_R_ERROR;
+
+ std::vector<std::pair<sqlite3*, uid_t>> conn_list = GetConnection();
+
+ bool is_writer = false;
+ for (auto& conn : conn_list) {
+ 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);
+ }
+
+ return GetHandleFromDB(conn_list);
+}
+
} // namespace database
} // namespace pkgmgr_server
class EXPORT_API AppInfoDBHandler : public AbstractDBHandler{
public:
AppInfoDBHandler(uid_t uid, int pid);
- ~AppInfoDBHandler();
+ virtual ~AppInfoDBHandler();
std::vector<std::shared_ptr<application_x>> GetAppHandle();
void SetFilter(pkgmgrinfo_filter_x* filter);
virtual int Execute();
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_;
--- /dev/null
+/*
+ * 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.
+ */
+
+#include "cache_db_handler.hh"
+
+#include <shared_mutex>
+#include <vector>
+
+#include "cache_flag.hh"
+#include "db_handle_provider.hh"
+#include "utils/logging.hh"
+
+namespace pkgmgr_server {
+namespace database {
+
+CacheDBHandler::CacheDBHandler(uid_t uid, int pid)
+ : AbstractDBHandler(uid, pid), uid_(uid) {}
+
+CacheDBHandler::~CacheDBHandler() {}
+
+int CacheDBHandler::Execute() {
+ std::shared_lock<std::shared_timed_mutex> s(lock_);
+ SetOpType(pkgmgr_common::DBOperationType::OPERATION_TYPE_READ);
+ SetDBType(pkgmgr_common::DBType::DB_TYPE_FILE_PKGDB);
+
+ std::vector<std::pair<sqlite3*, uid_t>> conn_list;
+ if (!Connect()) {
+ CacheFlag::SetStatus(CacheFlag::Status::UNPREPARED);
+ 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 (ret != PMINFO_R_OK) {
+ LOG(ERROR) << "Failed to update pkginfo cache : " << ret;
+ break;
+ }
+ }
+
+ CacheFlag::SetStatus(ret == PMINFO_R_OK ?
+ CacheFlag::Status::PREPARED :
+ CacheFlag::Status::UNPREPARED);
+
+ return ret;
+}
+
+} // namespace database
+} // namespace pkgmgr_server
--- /dev/null
+/*
+ * 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_DB_HANDLER_HH_
+#define CACHE_DB_HANDLER_HH_
+
+#include <vector>
+
+#include <sys/types.h>
+
+#include "abstract_db_handler.hh"
+#include "pkgmgrinfo_basic.h"
+#include "pkgmgrinfo_private.h"
+
+namespace pkgmgr_server {
+namespace database {
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+class EXPORT_API CacheDBHandler : public AbstractDBHandler {
+ public:
+ CacheDBHandler(uid_t uid, int pid);
+ ~CacheDBHandler();
+ int Execute();
+
+ protected:
+ pkgmgrinfo_filter_x* filter_ = nullptr;
+ std::vector<std::shared_ptr<package_x>> handle_list_;
+ uid_t uid_;
+};
+
+} // namespace database
+} // namespace pkgmgr_server
+
+#endif // CACHE_DB_HANDLER_HH_
#include <string>
#include <vector>
+#include "cache_flag.hh"
#include "utils/logging.hh"
#include "pkgmgr-info.h"
std::string DBHandleProvider::cert_file_db_path_;
std::unordered_set<pid_t> DBHandleProvider::pid_list_;
std::recursive_mutex DBHandleProvider::lock_;
+std::mutex DBHandleProvider::pid_list_lock_;
DBHandleProvider::DBHandleProvider(uid_t uid)
: uid_(uid),
}
bool DBHandleProvider::IsCrashedWriteRequest() {
- std::unique_lock<std::recursive_mutex> u(lock_);
+ std::unique_lock<std::mutex> u(pid_list_lock_);
if (pid_list_.empty())
return false;
if (cert_db != nullptr)
cert_memory_db_handle_.reset(cert_db);
- if (pid_list_.find(pid) == pid_list_.end())
- pid_list_.insert(pid);
+ InsertPID(pid);
}
is_memory_ = true;
is_memory_global_ = true;
- old_pkg_map_ = std::move(pkg_map_);
- old_app_map_ = std::move(app_map_);
- released_ = true;
LOG(DEBUG) << "Set Memory mode : Memory";
}
if (!is_memory_global_ && !is_memory_)
return;
+ auto lock = CacheFlag::GetWriterLock();
+ CacheFlag::SetStatus(CacheFlag::Status::PREPARING);
+
parser_memory_db_handle_.reset(nullptr);
cert_memory_db_handle_.reset(nullptr);
global_parser_memory_db_handle_.reset(nullptr);
- auto it = pid_list_.find(pid);
- if (it != pid_list_.end())
- pid_list_.erase(it);
- else
+ if (!ErasePID(pid))
LOG(ERROR) << "Given pid is not exists in pid list : " << pid;
is_memory_ = false;
is_memory_global_ = false;
- old_pkg_map_.clear();
- old_app_map_.clear();
+ pkg_map_.clear();
+ app_map_.clear();
+ CacheFlag::SetStatus(CacheFlag::Status::UNPREPARED);
LOG(DEBUG) << "Set Memory mode : File";
}
bool DBHandleProvider::IsMemoryDBActive(pid_t pid, bool write) {
+ std::unique_lock<std::mutex> u(pid_list_lock_);
return (is_memory_ && pid_list_.find(pid) == pid_list_.end() && !write);
}
}
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::NeedUpdate(pid_t pid, bool write,
- const std::string& locale) {
- std::unique_lock<std::recursive_mutex> u(lock_);
- return (!IsMemoryDBActive(pid, write) && (locale_ != locale || released_));
+bool DBHandleProvider::IsWriter(pid_t pid) {
+ std::unique_lock<std::mutex> u(pid_list_lock_);
+ return pid_list_.find(pid) != pid_list_.end();
}
int DBHandleProvider::UpdateCache(sqlite3* db, pid_t pid, uid_t uid, bool write,
const std::string& locale) {
- if (!NeedUpdate(pid, write, locale))
- return PMINFO_R_OK;
-
- std::unique_lock<std::recursive_mutex> u(lock_);
- if (!released_)
- ReleaseCache();
-
- locale_ = locale;
+ pkg_map_.clear();
+ app_map_.clear();
GHashTable* list = g_hash_table_new(g_str_hash, g_str_equal);
if (list == nullptr) {
}
int ret = pkginfo_internal_filter_get_list(db, tmp_filter, uid_,
- locale_.c_str(), list);
+ locale.c_str(), list);
if (ret == PMINFO_R_OK) {
GHashTableIter iter;
gpointer value;
list = g_hash_table_new(g_str_hash, g_str_equal);
ret = appinfo_internal_filter_get_list(db, tmp_filter, uid_, uid,
- locale_.c_str(), list);
+ locale.c_str(), list);
free(tmp_filter);
if (ret == PMINFO_R_OK) {
GHashTableIter iter;
std::vector<std::shared_ptr<package_x>> DBHandleProvider::GetPackages(
pid_t pid, bool write, pkgmgrinfo_filter_x* filter,
const std::string& package) {
- auto& pkg_map = (IsMemoryDBActive(pid, write) ? old_pkg_map_ : pkg_map_);
-
std::vector<std::shared_ptr<package_x>> ret;
- for (auto& info : pkg_map[package]) {
+ 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);
std::vector<std::shared_ptr<application_x>> DBHandleProvider::GetApplications(
pid_t pid, bool write, pkgmgrinfo_filter_x* filter,
const std::string& app) {
- auto& app_map = (IsMemoryDBActive(pid, write) ? old_app_map_ : app_map_);
-
/* 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)) {
}
std::vector<std::shared_ptr<application_x>> ret;
- for (auto& info : app_map[app]) {
+ 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);
app_map_[""].push_back(std::move(ptr));
}
+void DBHandleProvider::InsertPID(pid_t pid) {
+ std::unique_lock<std::mutex> u(pid_list_lock_);
+
+ pid_list_.insert(pid);
+}
+
+bool DBHandleProvider::ErasePID(pid_t pid) {
+ std::unique_lock<std::mutex> u(pid_list_lock_);
+
+ return pid_list_.erase(pid) == 1;
+}
+
} // namespace database
} // namespace pkgmgr_server
std::string GetCertDBPath(int pid, bool write);
void SetMemoryMode(pid_t pid);
void UnsetMemoryMode(pid_t pid);
- bool NeedUpdate(pid_t pid, bool write, const std::string& locale);
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& app);
void TrimCache();
+ bool IsWriter(pid_t pid);
private:
explicit DBHandleProvider(uid_t uid);
void ReleaseCache();
void AddPackage(std::string package, package_x* info);
void AddApplication(std::string app, application_x* info);
+ void InsertPID(pid_t pid);
+ bool ErasePID(pid_t pid);
private:
static std::unordered_map<uid_t, std::unique_ptr<DBHandleProvider>> provider_;
static std::string cert_file_db_path_;
static std::unordered_set<pid_t> pid_list_;
static std::recursive_mutex lock_;
+ static std::mutex pid_list_lock_;
uid_t uid_;
bool is_memory_;
parser_memory_db_handle_;
std::string parser_memory_db_path_;
std::string parser_file_db_path_;
- std::string locale_;
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<package_x>>>
- old_pkg_map_;
std::unordered_map<std::string, std::vector<std::shared_ptr<application_x>>>
app_map_;
- std::unordered_map<std::string, std::vector<std::shared_ptr<application_x>>>
- old_app_map_;
};
} // namespace database
+++ /dev/null
-/*
- * 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.
- */
-
-#include "pkg_get_cache_db_handler.hh"
-
-#include <shared_mutex>
-#include <vector>
-
-#include "utils/logging.hh"
-
-#include "db_handle_provider.hh"
-#include "pkgmgrinfo_debug.h"
-
-namespace pkgmgr_server {
-namespace database {
-
-PkgGetCacheDBHandler::PkgGetCacheDBHandler(uid_t uid, int pid)
- : PkgGetDBHandler(uid, pid) {}
-
-int PkgGetCacheDBHandler::Execute() {
- std::shared_lock<std::shared_timed_mutex> s(lock_);
- SetOpType(pkgmgr_common::DBOperationType::OPERATION_TYPE_READ);
- SetDBType(pkgmgr_common::DBType::DB_TYPE_FILE_PKGDB);
- bool write =
- GetOpType() == pkgmgr_common::DBOperationType::OPERATION_TYPE_WRITE;
-
- std::vector<std::pair<sqlite3*, uid_t>> conn_list;
- if (!Connect())
- return PMINFO_R_ERROR;
-
- conn_list = GetConnection();
-
- 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) {
- ret = DBHandleProvider::GetInst(conn.second)
- .UpdateCache(conn.first, GetPID(), uid_, write, GetLocale());
- if (ret != PMINFO_R_OK) {
- LOG(ERROR) << "Failed to update pkginfo cache : " << ret;
- break;
- }
-
- pkg_list = DBHandleProvider::GetInst(conn.second)
- .GetPackages(GetPID(), write, 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;
-}
-
-} // namespace database
-} // namespace pkgmgr_server
+++ /dev/null
-/*
- * 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 PKG_GET_CACHE_DB_HANDLER_HH_
-#define PKG_GET_CACHE_DB_HANDLER_HH_
-
-#include <sys/types.h>
-
-#include <vector>
-
-#include "pkg_get_db_handler.hh"
-#include "pkgmgrinfo_basic.h"
-#include "pkgmgrinfo_private.h"
-
-namespace pkgmgr_server {
-namespace database {
-
-#ifndef EXPORT_API
-#define EXPORT_API __attribute__((visibility("default")))
-#endif
-
-class EXPORT_API PkgGetCacheDBHandler : public PkgGetDBHandler {
- public:
- PkgGetCacheDBHandler(uid_t uid, int pid);
- int Execute() override;
-};
-
-} // namespace database
-} // namespace pkgmgr_server
-
-#endif // PKG_GET_CACHE_DB_HANDLER_HH_
#include <shared_mutex>
#include <vector>
+#include "cache_flag.hh"
+#include "db_handle_provider.hh"
+
#include "pkgmgrinfo_debug.h"
#include "pkgmgrinfo_internal.h"
#include "utils/logging.hh"
filter_ = filter;
}
-int PkgGetDBHandler::Execute() {
- std::shared_lock<std::shared_timed_mutex> s(lock_);
- SetOpType(pkgmgr_common::DBOperationType::OPERATION_TYPE_READ);
- SetDBType(pkgmgr_common::DBType::DB_TYPE_FILE_PKGDB);
- if (!Connect()) {
- LOG(ERROR) << "Failed to connect database";
- return PMINFO_R_ERROR;
- }
-
+int PkgGetDBHandler::GetHandleFromDB(
+ std::vector<std::pair<sqlite3*, uid_t>>& conn_list) {
GHashTable* list =
g_hash_table_new_full(g_str_hash, g_str_equal, nullptr, nullptr);
- std::vector<std::pair<sqlite3*, uid_t>> conn_list = GetConnection();
int ret = PMINFO_R_OK;
for (auto& conn : conn_list) {
ret = pkginfo_internal_filter_get_list(conn.first, filter_, conn.second,
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);
+ SetDBType(pkgmgr_common::DBType::DB_TYPE_FILE_PKGDB);
+ if (!Connect()) {
+ LOG(ERROR) << "Failed to connect database";
+ return PMINFO_R_ERROR;
+ }
+
+ std::vector<std::pair<sqlite3*, uid_t>> conn_list = GetConnection();
+
+ bool is_writer = false;
+ for (auto& conn : conn_list) {
+ 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);
+ }
+
+ return GetHandleFromDB(conn_list);
+}
+
} // namespace database
} // namespace pkgmgr_server
class EXPORT_API PkgGetDBHandler : public AbstractDBHandler {
public:
PkgGetDBHandler(uid_t uid, int pid);
- ~PkgGetDBHandler();
+ virtual ~PkgGetDBHandler();
std::vector<std::shared_ptr<package_x>> GetPkgHandle();
void SetFilter(pkgmgrinfo_filter_x* filter);
virtual int Execute();
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_;
class EXPORT_API PkgRequest {
public:
+ PkgRequest() = default;
PkgRequest(int fd);
~PkgRequest();
- unsigned char* GetData();
- int GetSize();
+
int GetFd();
- pid_t GetSenderPID();
- uid_t GetSenderUID();
- pkgmgr_common::ReqType GetRequestType();
bool ReceiveData();
- bool SendData(unsigned char* data, int size);
+
+ virtual unsigned char* GetData();
+ virtual int GetSize();
+ virtual pid_t GetSenderPID();
+ virtual uid_t GetSenderUID();
+ virtual pkgmgr_common::ReqType GetRequestType();
+ virtual bool SendData(unsigned char* data, int size);
private:
std::unique_ptr<pkgmgr_common::socket::DataSocket> socket_;
--- /dev/null
+// Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#include "create_cache_request_handler.hh"
+
+#include <string>
+
+#include "cache_db_handler.hh"
+
+namespace psd = pkgmgr_server::database;
+
+namespace pkgmgr_server {
+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());
+ db.SetLocale(locale);
+
+ int ret = db.Execute();
+
+ return ret == PMINFO_R_OK;
+}
+
+std::vector<uint8_t> CreateCacheRequestHandler::ExtractResult() {
+ return {};
+}
+
+} // namespace request_handler
+} // namespace pkgmgr_server
--- /dev/null
+// Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef CREATE_CACHE_REQUEST_HANDLER_HH_
+#define CREATE_CACHE_REQUEST_HANDLER_HH_
+
+#include "abstract_request_handler.hh"
+#include "result_parcelable.hh"
+
+#include <string>
+
+namespace pkgmgr_server {
+namespace request_handler {
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+class EXPORT_API CreateCacheRequestHandler : public AbstractRequestHandler {
+ public:
+ bool HandleRequest(unsigned char* data, int size,
+ const std::string& locale) override;
+ std::vector<uint8_t> ExtractResult() override;
+
+ private:
+ std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> result_;
+};
+
+} // namespace request_handler
+} // namespace pkgmgr_server
+
+#endif // CREATE_CACHE_REQUEST_HANDLER_HH_
\ No newline at end of file
#include <string>
-#include "appinfo_cache_db_handler.hh"
#include "appinfo_db_handler.hh"
#include "filter_parcelable.hh"
#include "parcelable_factory.hh"
return false;
}
- psd::AppInfoDBHandler* db;
- if (cache_)
- db = new psd::AppInfoCacheDBHandler(parcel->GetUid(), GetPID());
- else
- db = new psd::AppInfoDBHandler(parcel->GetUid(), GetPID());
+ psd::AppInfoDBHandler db(parcel->GetUid(), GetPID());
+ db.SetLocale(locale);
+ db.SetFilter(const_cast<pkgmgrinfo_filter_x*>(parcel->GetFilter()));
+ int ret = db.Execute();
- db->SetLocale(locale);
- db->SetFilter(const_cast<pkgmgrinfo_filter_x*>(parcel->GetFilter()));
- int ret = db->Execute();
+ result_ = std::make_shared<pcp::AppInfoParcelable>(ret, db.GetAppHandle());
- result_ = std::make_shared<pcp::AppInfoParcelable>(ret, db->GetAppHandle());
-
- delete db;
return true;
}
#include <string>
+#include "abstract_db_handler.hh"
#include "filter_parcelable.hh"
#include "parcelable_factory.hh"
-#include "pkg_get_cache_db_handler.hh"
#include "pkg_get_db_handler.hh"
#include "pkgmgrinfo_debug.h"
#include "utils/logging.hh"
return false;
}
- psd::PkgGetDBHandler* db;
- if (cache_)
- db = new psd::PkgGetCacheDBHandler(parcel->GetUid(), GetPID());
- else
- db = new psd::PkgGetDBHandler(parcel->GetUid(), GetPID());
+ psd::PkgGetDBHandler db(parcel->GetUid(), GetPID());
+ db.SetLocale(locale);
+ db.SetFilter(const_cast<pkgmgrinfo_filter_x*>(parcel->GetFilter()));
+ int ret = db.Execute();
- db->SetLocale(locale);
- db->SetFilter(const_cast<pkgmgrinfo_filter_x*>(parcel->GetFilter()));
- int ret = db->Execute();
+ result_ = std::make_shared<pcp::PkgInfoParcelable>(ret, db.GetPkgHandle());
- result_ = std::make_shared<pcp::PkgInfoParcelable>(ret, db->GetPkgHandle());
-
- delete db;
return true;
}
#include <unordered_map>
#include <vector>
+#include "cache_flag.hh"
+#include "create_cache_request.hh"
#include "cynara_checker.hh"
#include "pkg_request.hh"
#include "runner.hh"
auto req = std::make_shared<PkgRequest>(client_fd);
if (req->ReceiveData()) {
pkgmgr_common::ReqType type = req->GetRequestType();
+ if (CacheFlag::SetPreparing()) {
+ runner->QueueRequest(
+ std::make_shared<CreateCacheRequest>(req->GetSenderUID()));
+ }
std::vector<std::string>&& privileges = GetPrivileges(type);
CynaraChecker::GetInst().CheckPrivilege(runner, req, privileges);
}
#include "abstract_parcelable.hh"
#include "command_request_handler.hh"
+#include "create_cache_request_handler.hh"
#include "create_db_request_handler.hh"
#include "db_handle_provider.hh"
#include "get_appinfo_request_handler.hh"
new request_handler::CommandRequestHandler());
handler[pkgmgr_common::ReqType::CREATE_DB].reset(
new request_handler::CreateDBRequestHandler());
+ handler[pkgmgr_common::ReqType::CREATE_CACHE].reset(
+ new request_handler::CreateCacheRequestHandler());
LOG(DEBUG) << "Initialize request handlers";
while (true) {