#include <fcntl.h>
#include <unistd.h>
+#include <mutex>
+#include <shared_mutex>
#include <unordered_set>
#include "utils/logging.hh"
#undef LOG_TAG
#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_common {
namespace shared_memory {
+static const std::string APP_SHM_PREFIX = ".pkgmgr_info_app_";
+
inline bool CheckPrivilegeFilters(const char* pkgid, uid_t uid,
const std::unordered_set<std::string>& privilege_filters) {
ShmPkgReader pkg_reader(uid);
if (filter_checker.AppIdFilterValue()) {
for (auto& reader : readers_) {
- int result;
- auto handle = reader.GetHandle(filter_checker.AppIdFilterValue(), &result);
+ ShmError result;
+ auto handle = reader->GetHandle(filter_checker.AppIdFilterValue(), &result);
if (!handle) {
- if (result == TIZEN_ERROR_NO_DATA)
+ if (result == ShmError::NO_DATA)
continue;
- else if (result != TIZEN_ERROR_NONE)
+ else if (result != ShmError::NONE)
return PMINFO_R_ERROR;
} else {
if (filter_checker.Check(*handle))
}
} else {
for (auto& reader : readers_) {
- int result;
- auto handles = reader.GetHandles(&result);
- if (!handles && result != TIZEN_ERROR_NONE)
+ ShmError result;
+ auto handles = reader->GetHandles(&result);
+ if (!handles && result != ShmError::NONE)
return PMINFO_R_ERROR;
if (!handles)
ShmAppReader::ShmAppReader(uid_t uid) : uid_(uid) {
readers_.emplace_back(
- ShmNameProvider::AppConfig(uid),
- ShmNameProvider::AppHandle(uid),
- ShmNameProvider::AppIndexs(uid),
- ShmNameProvider::AppKeys(uid));
+ ShmAppReader::ShmAppReaderProvider::GetReader(uid));
if (uid > REGULAR_USER)
readers_.emplace_back(
- ShmNameProvider::AppConfig(GLOBAL_USER),
- ShmNameProvider::AppHandle(GLOBAL_USER),
- ShmNameProvider::AppIndexs(GLOBAL_USER),
- ShmNameProvider::AppKeys(GLOBAL_USER));
-}
-
-bool ShmAppReader::Init() {
- if (_is_writer()) {
- LOGD("process(%d) is writer", getpid());
- return false;
- }
-
- for (auto& reader : readers_) {
- if (!reader.Init()) {
- LOGE("Init reader fail");
- return false;
- }
- }
-
- return true;
+ ShmAppReader::ShmAppReaderProvider::GetReader(GLOBAL_USER));
}
ShmAppReader::FilterChecker::FilterChecker(uid_t uid)
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_PRIVILEGE)
+ continue;
+
filter_checker_.emplace_back(std::make_pair(FilterCheckerProvider::GetInst().
GetAppFilterChecker(node->prop), node->value));
}
return appid_filter_;
}
+ShmReader<AppInfoHandle>*
+ ShmAppReader::ShmAppReaderProvider::GetReader(uid_t uid) {
+ static std::shared_mutex lock_;
+ std::shared_lock<std::shared_mutex> s(lock_);
+
+ uid = ConvertUID(uid);
+ auto it = readers_map_.find(uid);
+ if (it != readers_map_.end())
+ return it->second;
+
+ s.unlock();
+ std::unique_lock<std::shared_mutex> u(lock_);
+ auto* prov = readers_map_[uid];
+ if (prov == nullptr)
+ readers_map_[uid] =
+ new ShmReader<AppInfoHandle>(APP_SHM_PREFIX + std::to_string(uid));
+
+ return readers_map_[uid];
+}
+
} // namespace shared_memory
} // namespace pkgmgr_common
public:
ShmAppReader(uid_t uid);
- bool Init();
int GetHandles(pkgmgrinfo_filter_x* filter,
std::map<std::string, AppInfoHandle>& list);
std::vector<std::pair<IAppFilterChecker*, const char*>> filter_checker_;
};
+ class EXPORT_API ShmAppReaderProvider {
+ public:
+ ShmAppReaderProvider() = delete;
+
+ static ShmReader<AppInfoHandle>* GetReader(uid_t uid);
+
+ private:
+ static inline std::unordered_map<uid_t,
+ ShmReader<AppInfoHandle>*> readers_map_;
+ };
+
+ private:
+ std::vector<ShmReader<AppInfoHandle>*> readers_;
uid_t uid_;
- std::vector<ShmReader<AppInfoHandle>> readers_;
};
} // namespace shared_memory
#undef LOG_TAG
#define LOG_TAG "PKGMGR_INFO"
-namespace {
-
-uid_t globaluser_uid = -1;
+namespace pkgmgr_common {
+namespace shared_memory {
-uid_t GetGlobalUID() {
- if (globaluser_uid == (uid_t)-1)
- globaluser_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
+ShmMapper::ShmMapper(std::string shm_name)
+ : shm_name_(std::move(shm_name)), fd_(-1), mapping_ptr_(nullptr) {}
- return globaluser_uid;
-}
+ShmMapper::~ShmMapper() {
+ if (mapping_ptr_) {
+ size_t target_size = GetPowerOfTwoSizeWithData(mapping_ptr_->mem_size);
+ LOGD("try to munmap (%p, %zu)", mapping_ptr_, target_size);
+ if (munmap(mapping_ptr_, target_size) != 0)
+ LOGE("Failed to munmap %s", shm_name_.c_str());
+ }
-uid_t ConvertUID(uid_t uid) {
- if (uid < REGULAR_USER)
- return GetGlobalUID();
- else
- return uid;
+ if (fd_ != -1) {
+ LOGW("close fd(%d)", fd_);
+ close(fd_);
+ }
}
-} // namespace
+uint8_t* ShmMapper::GetPtr() const {
+ if (!mapping_ptr_)
+ return nullptr;
-namespace pkgmgr_common {
-namespace shared_memory {
+ if (mapping_ptr_->mem_size == 0)
+ return nullptr;
-static constexpr const char PKG_CONFIG[] = ".pkgmgr_pkg_config";
-static constexpr const char PKG_HANDLE_SHM_NAME[] = ".pkgmgr_info_pkg_handle";
-static constexpr const char PKG_INDEXS_SHM_NAME[] = ".pkgmgr_info_pkg_indexs";
-static constexpr const char PKG_KEYS_SHM_NAME[] = ".pkgmgr_info_pkg_keys";
-static constexpr const char APP_CONFIG[] = ".pkgmgr_app_config";
-static constexpr const char APP_HANDLE_SHM_NAME[] = ".pkgmgr_info_app_handle";
-static constexpr const char APP_INDEXS_SHM_NAME[] = ".pkgmgr_info_app_indexs";
-static constexpr const char APP_KEYS_SHM_NAME[] = ".pkgmgr_info_app_keys";
-
-static std::string GetName(const char* prefix, uid_t uid) {
- return std::string(prefix) + "_" + std::to_string(uid);
+ return (uint8_t*)(mapping_ptr_ + 1);
}
-const char* ShmNameProvider::PkgConfig(uid_t uid) {
- uid = ConvertUID(uid);
- auto it = pkg_config_names_.find(uid);
- if (it != pkg_config_names_.end())
- return it->second.c_str();
+size_t ShmMapper::GetMemSize() const {
+ if (!mapping_ptr_)
+ return 0;
- return pkg_config_names_.emplace(uid, GetName(PKG_CONFIG, uid))
- .first->second.c_str();
+ return mapping_ptr_->mem_size;
}
-const char* ShmNameProvider::PkgHandle(uid_t uid) {
- uid = ConvertUID(uid);
- auto it = pkg_handle_names_.find(uid);
- if (it != pkg_handle_names_.end())
- return it->second.c_str();
-
- return pkg_handle_names_.emplace(uid, GetName(PKG_HANDLE_SHM_NAME, uid))
- .first->second.c_str();
+size_t ShmMapper::GetMemSizeWithData(size_t mem_size) {
+ return mem_size + sizeof(ShmData);
}
-const char* ShmNameProvider::PkgIndexs(uid_t uid) {
- uid = ConvertUID(uid);
- auto it = pkg_indexs_names_.find(uid);
- if (it != pkg_indexs_names_.end())
- return it->second.c_str();
-
- return pkg_indexs_names_.emplace(uid, GetName(PKG_INDEXS_SHM_NAME, uid))
- .first->second.c_str();
-}
+size_t ShmMapper::GetPowerOfTwoSizeWithData(size_t mem_size) {
+ mem_size += sizeof(ShmData);
+ size_t result = 1;
+ for (size_t i = 0; i < sizeof(mem_size) * 8 - 1; ++i) {
+ if (result >= mem_size)
+ break;
-const char* ShmNameProvider::PkgKeys(uid_t uid) {
- uid = ConvertUID(uid);
- auto it = pkg_keys_names_.find(uid);
- if (it != pkg_keys_names_.end())
- return it->second.c_str();
+ result <<= 1;
+ }
- return pkg_keys_names_.emplace(uid, GetName(PKG_KEYS_SHM_NAME, uid))
- .first->second.c_str();
+ return result;
}
-const char* ShmNameProvider::AppConfig(uid_t uid) {
- uid = ConvertUID(uid);
- auto it = app_config_names_.find(uid);
- if (it != app_config_names_.end())
- return it->second.c_str();
+ShmWriteMapper::ShmWriteMapper(std::string shm_name) :
+ ShmMapper(std::move(shm_name)), version_(1) {}
- return app_config_names_.emplace(uid, GetName(APP_CONFIG, uid))
- .first->second.c_str();
-}
+ShmWriteMapper::~ShmWriteMapper() {}
-const char* ShmNameProvider::AppHandle(uid_t uid) {
- uid = ConvertUID(uid);
- auto it = app_handle_names_.find(uid);
- if (it != app_handle_names_.end())
- return it->second.c_str();
+ShmError ShmWriteMapper::Init(size_t mem_size) {
+ LOGD("shm_unlink (%s)", shm_name_.c_str());
+ if (shm_unlink(shm_name_.c_str()) != 0)
+ LOGD("failed to unlink(%s) %d", shm_name_.c_str(), errno);
- return app_handle_names_.emplace(uid, GetName(APP_HANDLE_SHM_NAME, uid))
- .first->second.c_str();
-}
+ int fd = shm_open(shm_name_.c_str(), O_CREAT|O_RDWR, 0664);
+ if (fd == -1) {
+ LOGE("failed to open(%s). errno(%d)", shm_name_.c_str(), errno);
+ return ShmError::SYSTEM;
+ }
+ LOGD("shm_open success fd(%d)", fd);
-const char* ShmNameProvider::AppIndexs(uid_t uid) {
- uid = ConvertUID(uid);
- auto it = app_indexs_names_.find(uid);
- if (it != app_indexs_names_.end())
- return it->second.c_str();
+ size_t target_size = GetPowerOfTwoSizeWithData(mem_size);
+ if (ftruncate(fd, target_size) != 0) {
+ LOGE("failed to ftruncate (%zu), close fd(%d)", target_size, fd);
+ close(fd);
+ return ShmError::SYSTEM;
+ }
+ LOGD("ftruncate success fd(%d), size(%zu), name(%s)",
+ fd, target_size, shm_name_.c_str());
- return app_indexs_names_.emplace(uid, GetName(APP_INDEXS_SHM_NAME, uid))
- .first->second.c_str();
-}
+ uint8_t* mem_ptr =
+ (uint8_t*)mmap(NULL, target_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ if(mem_ptr == MAP_FAILED) {
+ LOGE("failed to mmap(%s), size(%zu). errno(%d)", shm_name_.c_str(), target_size, errno);
+ if(ftruncate(fd, 0) != 0)
+ LOGE("failed to truncate (%d:0)", fd);
-const char* ShmNameProvider::AppKeys(uid_t uid) {
- uid = ConvertUID(uid);
- auto it = app_keys_names_.find(uid);
- if (it != app_keys_names_.end())
- return it->second.c_str();
+ LOGD("shm_unlink (%s)", shm_name_.c_str());
+ shm_unlink(shm_name_.c_str());
+ LOGW("close fd(%d)", fd);
+ close(fd);
+ return ShmError::SYSTEM;
+ }
+ LOGD("mmap success (%p, %zu)", mem_ptr, target_size);
- return app_keys_names_.emplace(uid, GetName(APP_KEYS_SHM_NAME, uid))
- .first->second.c_str();
-}
+ fd_ = fd;
+ mapping_ptr_ = (ShmData*)mem_ptr;
+ mapping_ptr_->mem_size = mem_size;
+ mapping_ptr_->version = version_++;
-ShmMapper::ShmMapper(const char* shm_name)
- : shm_name_(shm_name), mem_size_(0), mem_ptr_(nullptr) {}
+ LOGD("[%s], memsize : %zu, version : %zu", shm_name_.c_str(), mapping_ptr_->mem_size, mapping_ptr_->version);
-ShmMapper::~ShmMapper() {
- if (mem_ptr_ && munmap(mem_ptr_, mem_size_) != 0)
- LOGE("Failed to munmap %s", shm_name_);
+ return ShmError::NONE;
}
-uint8_t* ShmMapper::GetPtr() const {
- return mem_ptr_;
-}
+ShmError ShmWriteMapper::Resize(size_t mem_size) {
+ if (!mapping_ptr_) {
+ LOGE("Invalid operation");
+ return ShmError::SYSTEM;
+ }
-size_t ShmMapper::GetSize() const {
- return mem_size_;
-}
+ size_t origin_size = GetPowerOfTwoSizeWithData(mapping_ptr_->mem_size);
+ size_t new_size = GetPowerOfTwoSizeWithData(mem_size);
-ShmWriteMapper::ShmWriteMapper(const char* shm_name) :
- ShmMapper(shm_name), fd_(-1) {}
+ if (origin_size == new_size) {
+ mapping_ptr_->mem_size = mem_size;
+ return ShmError::NONE;
+ }
-ShmWriteMapper::~ShmWriteMapper() {
- if (fd_ != -1)
- close(fd_);
- fd_ = -1;
-}
+ LOGD("try resize %zu(%zu) to %zu(%zu)",
+ mapping_ptr_->mem_size, origin_size,
+ mem_size, new_size);
-bool ShmWriteMapper::Init(size_t mem_size) {
- if(shm_unlink(shm_name_) != 0) {
- LOGD("failed to unlink(%s) %d", shm_name_, errno);
- } else {
- LOGD("success to unlink(%s)", shm_name_);
+ LOGD("try to munmap (%p, %zu)", mapping_ptr_, origin_size);
+ if (munmap(mapping_ptr_, origin_size) != 0) {
+ LOGE("Failed to munmap %s", shm_name_.c_str());
+ return ShmError::SYSTEM;
}
- int fd = shm_open(shm_name_, O_CREAT|O_RDWR, 0664);
- if(fd == -1) {
- LOGE("failed to open(%s). errno(%d)", shm_name_, errno);
- return false;
+ if (ftruncate(fd_, new_size) != 0) {
+ LOGE("failed to truncate (%d:%zu), %s", fd_, new_size, shm_name_.c_str());
+ return ShmError::SYSTEM;
}
+ LOGD("ftruncate success fd(%d), size(%zu), name(%s)",
+ fd_, new_size, shm_name_.c_str());
- if(ftruncate(fd, mem_size) != 0) {
- LOGE("failed to truncate (%d:%zu)", fd, mem_size);
- close(fd);
- return false;
+ uint8_t* mem_ptr = (uint8_t*)mmap(NULL, new_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd_, 0);
+ if(mem_ptr == MAP_FAILED) {
+ LOGE("failed to mmap(%s). errno(%d)", shm_name_.c_str(), errno);
+ if(ftruncate(fd_, 0) != 0)
+ LOGE("failed to truncate (%d:0)", fd_);
+
+ LOGD("shm_unlink (%s)", shm_name_.c_str());
+ shm_unlink(shm_name_.c_str());
+ LOGW("close fd(%d)", fd_);
+ close(fd_);
+ fd_ = -1;
+ mapping_ptr_ = nullptr;
+ version_ = 0;
+ return ShmError::SYSTEM;
}
+ LOGD("mmap success (%p, %zu)", mem_ptr, new_size);
+
+ mapping_ptr_ = (ShmData*)mem_ptr;
+ mapping_ptr_->mem_size = mem_size;
+ mapping_ptr_->version = version_++;
+
+ return ShmError::NONE;
+}
+
+ShmError ShmWriteMapper::Clear() {
+ version_ = 1;
- uint8_t* mem_ptr = nullptr;
- if (mem_size != 0) {
- mem_ptr = (uint8_t*)mmap(NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- if(mem_ptr == MAP_FAILED) {
- LOGE("failed to mmap(%s), size(%zu). errno(%d)", shm_name_, mem_size, errno);
- if(ftruncate(fd, 0) != 0)
- LOGE("failed to truncate (%d:0)", fd);
+ if (fd_ != -1) {
+ LOGW("close shm(%s), fd(%d)", shm_name_.c_str(), fd_);
+ close(fd_);
+ fd_ = -1;
+ }
- shm_unlink(shm_name_);
- close(fd);
- return false;
+ if (mapping_ptr_) {
+ size_t target_size = GetPowerOfTwoSizeWithData(mapping_ptr_->mem_size);
+ LOGD("try to munmap (%p, %zu)", mapping_ptr_, target_size);
+ if (munmap(mapping_ptr_, target_size) != 0) {
+ LOGE("Failed to munmap %s", shm_name_.c_str());
+ return ShmError::SYSTEM;
}
+
+ mapping_ptr_ = nullptr;
}
- fd_ = fd;
- mem_size_ = mem_size;
- mem_ptr_ = mem_ptr;
+ return ShmError::NONE;
+}
- return true;
+size_t ShmWriteMapper::GetVersion() const {
+ return version_;
}
-bool ShmWriteMapper::Resize(size_t mem_size) {
- LOGD("try resize %zu to %zu", mem_size_, mem_size);
+ShmReadMapper::ShmReadMapper(std::string shm_name) :
+ ShmMapper(std::move(shm_name)), last_version_(0), last_mem_size_(0) {}
- if (munmap(mem_ptr_, mem_size_) != 0) {
- LOGE("Failed to munmap %s", shm_name_);
- return false;
- }
+ShmReadMapper::~ShmReadMapper() {}
- if (ftruncate(fd_, mem_size) != 0) {
- LOGE("failed to truncate (%d:%zu), %s", fd_, mem_size, shm_name_);
- return false;
+ShmError ShmReadMapper::Init() {
+ if(fd_ > 0) return ShmError::NONE;
+
+ fd_ = shm_open(shm_name_.c_str(), O_RDONLY, 0664);
+ if (fd_ == -1) {
+ LOGE("failed to open(%s). errno(%d)", shm_name_.c_str(), errno);
+ fd_ = -1;
+ return (errno == ENOENT) ? ShmError::SHM_NOT_EXIST : ShmError::SYSTEM;
}
+ LOGD("shm_open success fd(%d)", fd_);
- uint8_t* mem_ptr = (uint8_t*)mmap(NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd_, 0);
- if(mem_ptr == MAP_FAILED) {
- LOGE("failed to mmap(%s). errno(%d)", shm_name_, errno);
- if(ftruncate(fd_, 0) != 0)
- LOGE("failed to truncate (%d:0)", fd_);
+ ShmData data;
+ ssize_t bytes_read = read(fd_, &data, sizeof(data));
+ if (bytes_read == -1) {
+ LOGE("failed to read shm data, error(%d)", errno);
+ return ShmError::SYSTEM;
+ }
- shm_unlink(shm_name_);
+ if (MappingShm(data.mem_size, data.version) != ShmError::NONE) {
+ LOGE("failed to load shared memroy, close fd(%d)", fd_);
close(fd_);
fd_ = -1;
- return false;
+ return ShmError::SYSTEM;
+ }
+
+ return ShmError::NONE;
+}
+
+ShmError ShmReadMapper::MappingShm(size_t mem_size, size_t version) {
+ if (mapping_ptr_) {
+ size_t mapping_size = GetPowerOfTwoSizeWithData(last_mem_size_);
+ LOGD("try to munmap (%p, %zu)", mapping_ptr_, mapping_size);
+ if (munmap(mapping_ptr_, mapping_size) != 0) {
+ LOGE("Failed to munmap %s", shm_name_.c_str());
+ mapping_ptr_ = nullptr;
+ return ShmError::SYSTEM;
+ }
+ }
+
+ size_t target_size = GetPowerOfTwoSizeWithData(mem_size);
+ uint8_t* shm = (uint8_t*)mmap(NULL, target_size, PROT_READ, MAP_SHARED, fd_, 0);
+ if (shm == MAP_FAILED) {
+ LOGE("failed to mmap(%s). fd(%d), errno(%d)", shm_name_.c_str(), fd_, errno);
+ mapping_ptr_ = nullptr;
+ return ShmError::SYSTEM;
}
+ LOGD("mmap (%p, %zu) success", shm, target_size);
- mem_size_ = mem_size;
- mem_ptr_ = mem_ptr;
+ mapping_ptr_ = (ShmData*)shm;
+ last_version_ = mapping_ptr_->version;
+ last_mem_size_ = mapping_ptr_->mem_size;
- return true;
+ return ShmError::NONE;
}
-ShmReadMapper::ShmReadMapper(const char* shm_name) :
- ShmMapper(shm_name), fd_(-1) {}
+ShmError ShmReadMapper::LoadAll() {
+ std::shared_lock<std::shared_mutex> s(lock_);
+ if (fd_ == -1) {
+ s.unlock();
+ std::unique_lock<std::shared_mutex> u(lock_);
-ShmReadMapper::~ShmReadMapper() {
- if (fd_ != -1)
- close(fd_);
- fd_ = -1;
+ if (fd_ != -1)
+ return ShmError::NONE;
+
+ return Init();
+ }
+
+ if (mapping_ptr_) {
+ if (last_version_ == mapping_ptr_->version)
+ return ShmError::NONE;
+
+ LOGD("last_version_ : %zu, new_version : %zu",
+ last_version_, mapping_ptr_->version);
+ s.unlock();
+ std::unique_lock<std::shared_mutex> u(lock_);
+ if (last_version_ == mapping_ptr_->version)
+ return ShmError::NONE;
+
+ return MappingShm(mapping_ptr_->mem_size, mapping_ptr_->version);
+ } else {
+ s.unlock();
+ std::unique_lock<std::shared_mutex> u(lock_);
+ if (mapping_ptr_)
+ return ShmError::NONE;
+
+ return Init();
+ }
}
-bool ShmReadMapper::Init() {
- if(fd_ > 0) return true;
+ShmError ShmReadMapper::Reload() {
+ std::unique_lock<std::shared_mutex> u(lock_);
+ size_t mapping_size = GetPowerOfTwoSizeWithData(last_mem_size_);
- int fd = shm_open(shm_name_, O_RDONLY, 0664);
- if(fd == -1) {
- LOGE("failed to open(%s). errno(%d)", shm_name_, errno);
- return false;
+ if (mapping_ptr_) {
+ LOGD("try to munmap (%p, %zu)", mapping_ptr_, mapping_size);
+ if (munmap(mapping_ptr_, mapping_size) != 0)
+ LOGE("Failed to munmap %s", shm_name_.c_str());
}
+ mapping_ptr_ = nullptr;
+ fd_ = -1;
- fd_ = fd;
- return true;
+ return Init();
}
-bool ShmReadMapper::LoadAll(size_t mem_size) {
- if(mem_ptr_){
- if (mem_size == mem_size_) {
- return true;
- } else {
- if (munmap(mem_ptr_, mem_size_) != 0) {
- LOGE("Failed to munmap %s", shm_name_);
- return false;
- }
- mem_ptr_ = nullptr;
- mem_size_ = 0;
+ShmError ShmReadMapper::Unload() {
+ std::unique_lock<std::shared_mutex> u(lock_);
+ if (!mapping_ptr_ && fd_ == -1)
+ return ShmError::NONE;
+
+ ShmError result = ShmError::NONE;
+ if (mapping_ptr_) {
+ size_t mapping_size = GetPowerOfTwoSizeWithData(last_mem_size_);
+ LOGD("try to munmap (%p, %zu)", mapping_ptr_, mapping_size);
+ if (munmap(mapping_ptr_, mapping_size) != 0) {
+ LOGE("Failed to munmap %s", shm_name_.c_str());
+ result = ShmError::SYSTEM;
}
+
+ mapping_ptr_ = nullptr;
}
- uint8_t* shm = (uint8_t*)mmap(NULL, mem_size, PROT_READ, MAP_SHARED, fd_, 0);
- if (shm == MAP_FAILED) {
- LOGE("failed to mmap(%s). errno(%d)", shm_name_, errno);
+ if (fd_) {
+ LOGW("close fd(%d)", fd_);
close(fd_);
fd_ = -1;
- mem_ptr_ = nullptr;
- mem_size_ = 0;
- return false;
}
- mem_ptr_ = shm;
- mem_size_ = mem_size;
+ return result;
+}
+
+ShmLockGuard::ShmLockGuard(pthread_rwlock_t* lock) : lock_(lock) {}
- return true;
+ShmLockGuard::~ShmLockGuard() {
+ if (!lock_)
+ return;
+
+ Unlock();
}
-uint8_t* ShmReadMapper::CopyPartial(size_t offset, size_t size) {
- uint8_t* ptr = reinterpret_cast<uint8_t*>(malloc(size));
- if (ptr == nullptr) {
- LOGE("Out of memory, len(%zu)", size);
- close(fd_);
- fd_ = -1;
- return nullptr;
+ShmLockGuard::ShmLockGuard(ShmLockGuard&& guard) noexcept {
+ lock_ = guard.lock_;
+ guard.lock_ = nullptr;
+}
+
+ShmLockGuard& ShmLockGuard::operator=(ShmLockGuard&& guard) noexcept {
+ if (this != &guard) {
+ lock_ = guard.lock_;
+ guard.lock_ = nullptr;
}
+ return *this;
+}
- if (mem_ptr_ && ((offset + size) < mem_size_)) {// case in-mmap, read mem
- memcpy(ptr, mem_ptr_, size);
- } else { // case out-mmap, read file
- if (lseek(fd_, offset, SEEK_SET) == -1) {
- LOGE("lseek fail fd(%d), index(%zd)", fd_, offset);
- free(ptr);
- close(fd_);
- fd_ = -1;
- return nullptr;
- }
+void ShmLockGuard::Unlock() {
+ if (!lock_)
+ return;
- ssize_t read_num = read(fd_, ptr, size);
- LOGD("read_num: %zd, len: %zu", read_num, size);
- if (read_num == -1) {
- LOGE("Failed to read %zu bytes, read_num(%zd)", size, read_num);
- free(ptr);
- close(fd_);
- fd_ = -1;
- return nullptr;
- }
+ LOGD("try unlock (%p)", lock_);
+ int ret = pthread_rwlock_unlock(lock_);
+ if (ret != 0) {
+ LOGE("Failed to unlock, %d", ret);
+ return;
}
- return ptr;
+
+ lock_ = nullptr;
}
ShmConfigHandler::~ShmConfigHandler() {
- if (has_lock_) {
- Unlock();
+ if (config_data_) {
+ LOGD("try to munmap (%p, %zu)", config_data_, sizeof(ConfigData));
+ if (munmap(config_data_, sizeof(config_data_)) != 0) {
+ LOGE("Failed to munmap %s", shm_name_.c_str());
+ return;
+ }
}
-
- if (config_data_)
- munmap(config_data_, sizeof(ConfigData));
}
-bool ShmConfigHandler::Create() {
- if(shm_unlink(shm_name_) != 0) {
- LOGD("failed to unlink(%s) %d", shm_name_, errno);
- } else {
- LOGD("success to unlink(%s)", shm_name_);
- }
+ShmError ShmConfigHandler::Create() {
+ std::unique_lock<std::shared_mutex> u(lock_);
+ LOGD("shm_unlink (%s)", shm_name_.c_str());
+ if (shm_unlink(shm_name_.c_str()) != 0)
+ LOGD("failed to unlink(%s) %d", shm_name_.c_str(), errno);
- int fd = shm_open(shm_name_, O_CREAT|O_RDWR, 0664);
+ int fd = shm_open(shm_name_.c_str(), O_CREAT|O_RDWR, 0664);
if(fd == -1) {
- LOGE("failed to open(%s). errno(%d)", shm_name_, errno);
- return false;
+ LOGE("failed to open(%s). errno(%d)", shm_name_.c_str(), errno);
+ return ShmError::SYSTEM;
}
+ LOGD("shm_open success fd(%d)", fd);
if (fchmod(fd, 0666) != 0) {
LOGE("Failed to change permission to 0666, %d", errno);
- return false;
+ return ShmError::SYSTEM;
}
size_t len = sizeof(ConfigData);
- LOGD("config_data len : %zu", len);
- LOGD("pthread_rwlock_t len : %zu", sizeof(pthread_rwlock_t));
if(ftruncate(fd, len) != 0) {
- LOGE("failed to truncate (%d:%zu)", fd, len);
+ LOGE("failed to truncate (%d:%zu), close fd(%d)", fd, len, fd);
close(fd);
- return false;
+ return ShmError::SYSTEM;
}
+ LOGD("ftruncate success fd(%d), size(%zu), name(%s)",
+ fd, len, shm_name_.c_str());
config_data_ = (ConfigData*)mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if(config_data_ == MAP_FAILED) {
- LOGE("failed to mmap(%s). errno(%d)", shm_name_, errno);
+ LOGE("failed to mmap(%s). errno(%d)", shm_name_.c_str(), errno);
if(ftruncate(fd, 0) != 0)
LOGE("failed to truncate (%d:0)", fd);
- shm_unlink(shm_name_);
+ LOGD("shm_unlink (%s)", shm_name_.c_str());
+ shm_unlink(shm_name_.c_str());
+ LOGW("close fd(%d)", fd);
close(fd);
- return false;
+ return ShmError::SYSTEM;
}
+ LOGD("mmap success (%p, %zu)", config_data_, len);
+ LOGW("close fd(%d)", fd);
close(fd);
pthread_rwlockattr_t attr;
if (pthread_rwlockattr_init(&attr)) {
LOGE("pthread_mutexattr_init fail");
- return false;
+ return ShmError::SYSTEM;
}
if (pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)) {
LOGE("pthread_mutexattr_setpshared fail");
pthread_rwlockattr_destroy(&attr);
- return false;
+ return ShmError::SYSTEM;
}
if (pthread_rwlock_init(&config_data_->lock, &attr)) {
LOGE("pthread_mutex_init fail");
pthread_rwlockattr_destroy(&attr);
- return false;
+ return ShmError::SYSTEM;
}
if (pthread_rwlockattr_destroy(&attr)) {
LOGE("pthread_rwlockattr_destroy fail");
- return false;
+ return ShmError::SYSTEM;
}
- return true;
+ return ShmError::NONE;
}
-bool ShmConfigHandler::Load() {
- int fd = shm_open(shm_name_, O_RDWR, 0664);
+ShmError ShmConfigHandler::Load() {
+ {
+ std::shared_lock<std::shared_mutex> s(lock_);
+ if (config_data_ != nullptr)
+ return ShmError::NONE;
+ }
+
+ std::unique_lock<std::shared_mutex> u(lock_);
+ if (config_data_ != nullptr)
+ return ShmError::NONE;
+
+ int fd = shm_open(shm_name_.c_str(), O_RDWR, 0664);
if(fd == -1) {
- LOGE("failed to open(%s). errno(%d)", shm_name_, errno);
- return false;
+ LOGE("failed to open(%s). errno(%d)", shm_name_.c_str(), errno);
+ return (errno == ENOENT) ? ShmError::SHM_NOT_EXIST : ShmError::SYSTEM;
}
+ LOGD("shm_open success fd(%d)", fd);
- config_data_ = (ConfigData*)mmap(NULL, sizeof(ConfigData), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- if(config_data_ == MAP_FAILED) {
- LOGE("failed to mmap(%s). errno(%d)", shm_name_, errno);
+ ConfigData* map_ptr = (ConfigData*)mmap(NULL, sizeof(ConfigData), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ if(map_ptr == MAP_FAILED) {
+ LOGE("failed to mmap(%s). errno(%d), close fd(%d)", shm_name_.c_str(), errno, fd);
close(fd);
- return false;
+ return ShmError::SYSTEM;
}
+ LOGD("mmap success (%p, %zu)", map_ptr, sizeof(ConfigData));
+ LOGW("close fd(%d)", fd);
close(fd);
- return true;
+ config_data_ = map_ptr;
+
+ return ShmError::NONE;
}
-int ShmConfigHandler::GetWriteLock() {
- if (has_lock_) {
- LOGD("This object already has lock");
- return 0;
+ShmError ShmConfigHandler::Clear() {
+ std::unique_lock<std::shared_mutex> u(lock_);
+
+ if (!config_data_)
+ return ShmError::NONE;
+
+ LOGD("try to munmap (%p, %zu)", config_data_, sizeof(ConfigData));
+ if (munmap(config_data_, sizeof(config_data_)) != 0) {
+ LOGE("Failed to munmap %s", shm_name_.c_str());
+ return ShmError::SYSTEM;
+ }
+
+ LOGD("shm_unlink (%s)", shm_name_.c_str());
+ if (shm_unlink(shm_name_.c_str()) != 0) {
+ LOGE("Failed to unlink(%s) %d", shm_name_.c_str(), errno);
+ return ShmError::SYSTEM;
+ }
+
+ config_data_ = nullptr;
+
+ return ShmError::NONE;
+}
+
+ShmError ShmConfigHandler::Reload() {
+ std::unique_lock<std::shared_mutex> u(lock_);
+
+ if (config_data_) {
+ LOGD("try to munmap (%p, %zu)", config_data_, sizeof(config_data_));
+ if (munmap(config_data_, sizeof(config_data_)) != 0)
+ LOGE("Failed to munmap %s", shm_name_.c_str());
+ }
+
+ config_data_ = nullptr;
+
+ int fd = shm_open(shm_name_.c_str(), O_RDWR, 0664);
+ if(fd == -1) {
+ LOGE("failed to open(%s). errno(%d)", shm_name_.c_str(), errno);
+ return (errno == ENOENT) ? ShmError::SHM_NOT_EXIST : ShmError::SYSTEM;
+ }
+ LOGD("shm_open success fd(%d)", fd);
+
+ ConfigData* map_ptr = (ConfigData*)mmap(NULL, sizeof(ConfigData), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ if(map_ptr == MAP_FAILED) {
+ LOGE("failed to mmap(%s). errno(%d), close fd(%d)", shm_name_.c_str(), errno, fd);
+ close(fd);
+ return ShmError::SYSTEM;
}
+ LOGD("mmap success (%p, %zu)", map_ptr, sizeof(ConfigData));
+ LOGW("close fd(%d)", fd);
+ close(fd);
+
+ config_data_ = map_ptr;
+
+ return ShmError::NONE;
+}
+
+ShmError ShmConfigHandler::Unload() {
+ if (!config_data_)
+ return ShmError::NONE;
+
+ LOGD("try to munmap (%p, %zu)", config_data_, sizeof(config_data_));
+ if (munmap(config_data_, sizeof(config_data_)) != 0)
+ LOGE("Failed to munmap %s", shm_name_.c_str());
+ config_data_ = nullptr;
+
+ return ShmError::NONE;
+}
+
+std::optional<ShmLockGuard> ShmConfigHandler::GetWriteLock() {
timespec timeout;
clock_gettime(CLOCK_REALTIME, &timeout);
- timeout.tv_sec += 30;
+ timeout.tv_sec += 5;
- LOGD("try get write lock");
int ret = pthread_rwlock_timedwrlock(&config_data_->lock, &timeout);
if (ret != 0) {
LOGE("Failed to get write lock, %d", ret);
- return ret;
+ return std::nullopt;
}
+ LOGD("sucess to get write lock of (%s), (%p)",
+ shm_name_.c_str(), &config_data_->lock);
- has_lock_ = true;
- return 0;
+ return ShmLockGuard(&config_data_->lock);
}
-int ShmConfigHandler::GetReadLock() {
- if (has_lock_) {
- LOGD("This object already has lock");
- return 0;
- }
-
- LOGD("try get read lock");
+std::optional<ShmLockGuard> ShmConfigHandler::GetReadLock() {
int ret = pthread_rwlock_tryrdlock(&config_data_->lock);
if (ret != 0) {
LOGE("Failed to get read lock, %d", ret);
- return ret;
+ return std::nullopt;
}
+ LOGD("sucess to get read lock of (%s), (%p)",
+ shm_name_.c_str(), &config_data_->lock);
- has_lock_ = true;
- return 0;
+ return ShmLockGuard(&config_data_->lock);
}
-int ShmConfigHandler::Unlock() {
- if (!has_lock_) {
- LOGD("This object doesn't have a lock");
- return 0;
- }
- LOGD("try unlock");
- int ret = pthread_rwlock_unlock(&config_data_->lock);
+bool ShmConfigHandler::GetIsValid() const {
+ if (config_data_ == nullptr)
+ return false;
+
+ int ret = pthread_rwlock_rdlock(&config_data_->flag_lock);
if (ret != 0) {
- LOGE("Failed to unlock, %d", ret);
- return ret;
+ LOGE("Failed to get flag lock, %d", ret);
+ return false;
}
- has_lock_ = false;
- return ret;
+ ShmLockGuard lock_guard(&config_data_->flag_lock);
+ return config_data_->is_valid;
}
-size_t ShmConfigHandler::GetMemSize() const {
- return config_data_->mem_size;
-}
+void ShmConfigHandler::SetIsValid(bool is_valid) {
+ if (!config_data_)
+ return;
-size_t ShmConfigHandler::GetIndexMemSize() const {
- return config_data_->index_mem_size;
-}
+ timespec timeout;
+ clock_gettime(CLOCK_REALTIME, &timeout);
+ timeout.tv_sec += 5;
-size_t ShmConfigHandler::GetKeyMemSize() const {
- return config_data_->key_mem_size;
-}
+ int ret = pthread_rwlock_timedwrlock(&config_data_->flag_lock, &timeout);
+ if (ret != 0) {
+ LOGE("Failed to get flag lock, %d", ret);
+ // There is a high possibility that reader terminated abnormaly by holding the lock
+ config_data_->is_valid = is_valid;
+ return;
+ }
-void ShmConfigHandler::SetMemSize(size_t mem_size) {
- config_data_->mem_size = mem_size;
-}
+ LOGD("sucess to get flag lock of (%s), (%p)",
+ shm_name_.c_str(), &config_data_->flag_lock);
-void ShmConfigHandler::SetIndexMemSize(size_t index_mem_size) {
- config_data_->index_mem_size = index_mem_size;
-}
+ ShmLockGuard lock_guard(&config_data_->flag_lock);
-void ShmConfigHandler::SetKeyMemSize(size_t key_mem_size) {
- config_data_->key_mem_size = key_mem_size;
+ config_data_->is_valid = is_valid;
}
#include <sys/types.h>
#include <map>
+#include <mutex>
+#include <optional>
+#include <shared_mutex>
#include <string>
namespace pkgmgr_common {
#define EXPORT_API __attribute__((visibility("default")))
#endif
-class EXPORT_API ShmNameProvider {
- public:
- static const char* PkgConfig(uid_t uid);
- static const char* PkgHandle(uid_t uid);
- static const char* PkgIndexs(uid_t uid);
- static const char* PkgKeys(uid_t uid);
- static const char* AppConfig(uid_t uid);
- static const char* AppHandle(uid_t uid);
- static const char* AppIndexs(uid_t uid);
- static const char* AppKeys(uid_t uid);
-
- private:
- ShmNameProvider() = delete;
- static inline std::map<uid_t, std::string> pkg_config_names_;
- static inline std::map<uid_t, std::string> pkg_handle_names_;
- static inline std::map<uid_t, std::string> pkg_indexs_names_;
- static inline std::map<uid_t, std::string> pkg_keys_names_;
- static inline std::map<uid_t, std::string> app_config_names_;
- static inline std::map<uid_t, std::string> app_handle_names_;
- static inline std::map<uid_t, std::string> app_indexs_names_;
- static inline std::map<uid_t, std::string> app_keys_names_;
+enum class EXPORT_API ShmError {
+ READ_LOCK,
+ SHM_NOT_EXIST,
+ SYSTEM,
+ PERMISSION,
+ NO_DATA,
+ INVALID_FLAG,
+ NONE,
};
class EXPORT_API ShmMapper {
public:
- ShmMapper(const char* shm_name);
+ ShmMapper(std::string shm_name);
virtual ~ShmMapper();
uint8_t* GetPtr() const;
- size_t GetSize() const;
+ size_t GetMemSize() const;
protected:
- const char* shm_name_;
- size_t mem_size_;
- uint8_t* mem_ptr_;
+ struct ShmData {
+ size_t mem_size;
+ size_t version;
+ };
+
+ size_t GetMemSizeWithData(size_t mem_size);
+ size_t GetPowerOfTwoSizeWithData(size_t mem_size);
+
+ std::string shm_name_;
+ int fd_;
+ ShmData* mapping_ptr_;
};
class EXPORT_API ShmWriteMapper : public ShmMapper {
public:
- ShmWriteMapper(const char* shm_name);
+ ShmWriteMapper(std::string shm_name);
~ShmWriteMapper();
- bool Init(size_t mem_size);
- bool Resize(size_t mem_size);
+ ShmError Init(size_t mem_size);
+ ShmError Resize(size_t mem_size);
+ ShmError Clear();
+ size_t GetVersion() const;
private:
- int fd_;
+ size_t version_;
};
class EXPORT_API ShmReadMapper : public ShmMapper {
public:
- ShmReadMapper(const char* shm_name);
+ ShmReadMapper(std::string shm_name);
~ShmReadMapper();
- bool Init();
- bool LoadAll(size_t mem_size);
- uint8_t* CopyPartial(size_t offset, size_t size);
+ ShmError LoadAll();
+ ShmError Reload();
+ ShmError Unload();
private:
- int fd_;
+ ShmError Init();
+ ShmError MappingShm(size_t mem_size, size_t version);
+
+ size_t last_version_;
+ size_t last_mem_size_;
+ std::shared_mutex lock_;
+};
+
+class EXPORT_API ShmLockGuard {
+ public:
+ ShmLockGuard(pthread_rwlock_t* lock);
+ ~ShmLockGuard();
+ ShmLockGuard(const ShmLockGuard&) = delete;
+ ShmLockGuard(ShmLockGuard&& guard) noexcept;
+ ShmLockGuard& operator=(ShmLockGuard&& p) noexcept;
+
+ void Unlock();
+
+ private:
+ pthread_rwlock_t* lock_;
};
class EXPORT_API ShmConfigHandler {
public:
- ShmConfigHandler(const char* shm_name) :
- config_data_(nullptr), has_lock_(false), shm_name_(shm_name) {}
+ ShmConfigHandler(std::string shm_name) :
+ config_data_(nullptr), shm_name_(std::move(shm_name)) {}
~ShmConfigHandler();
- bool Create();
- bool Load();
- int GetWriteLock();
- int GetReadLock();
- int Unlock();
- size_t GetMemSize() const;
- size_t GetIndexMemSize() const;
- size_t GetKeyMemSize() const;
- void SetMemSize(size_t app_mem_size);
- void SetIndexMemSize(size_t app_index_mem_size);
- void SetKeyMemSize(size_t pkg_mem_size);
+ ShmError Create();
+ ShmError Load();
+ ShmError Clear();
+ ShmError Reload();
+ ShmError Unload();
+ std::optional<ShmLockGuard> GetWriteLock();
+ std::optional<ShmLockGuard> GetReadLock();
+ bool GetIsValid() const;
+ void SetIsValid(bool is_valid);
private:
struct ConfigData {
pthread_rwlock_t lock;
- size_t mem_size;
- size_t index_mem_size;
- size_t key_mem_size;
+ pthread_rwlock_t flag_lock;
+ bool is_valid;
};
ConfigData* config_data_;
- bool has_lock_;
- const char* shm_name_;
+ std::string shm_name_;
+ std::shared_mutex lock_;
};
struct HandleMappingData {
#include <fcntl.h>
#include <unistd.h>
+#include <mutex>
+#include <shared_mutex>
+
#include "utils/logging.hh"
#include "pkgmgrinfo_private.h"
#undef LOG_TAG
#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_common {
namespace shared_memory {
+static const std::string PKG_SHM_PREFIX = ".pkgmgr_info_pkg_";
+
inline bool CheckMetadataFilter(const PkgInfoHandle* info,
const std::unordered_map<std::string, std::string>& metadata_map) {
for (auto node : info->GetMetadata()) {
}
if (filter_checker.PkgIdFilterValue()) {
- for (auto& reader : readers_) {
- int result;
- auto handle = reader.GetHandle(filter_checker.PkgIdFilterValue(), &result);
+ for (auto reader : readers_) {
+ ShmError result;
+ auto handle = reader->GetHandle(filter_checker.PkgIdFilterValue(), &result);
if (!handle) {
- if (result == TIZEN_ERROR_NO_DATA)
+ if (result == ShmError::NO_DATA)
continue;
- else if (result != TIZEN_ERROR_NONE)
+ else if (result != ShmError::NONE)
return PMINFO_R_ERROR;
} else {
if (filter_checker.Check(*handle))
}
}
} else {
- for (auto& reader : readers_) {
- int result;
- auto handles = reader.GetHandles(&result);
- if (!handles && result != TIZEN_ERROR_NONE)
+ for (auto reader : readers_) {
+ ShmError result;
+ auto handles = reader->GetHandles(&result);
+ if (!handles && result != ShmError::NONE)
return PMINFO_R_ERROR;
if (!handles)
}
std::optional<PkgInfoHandle> ShmPkgReader::GetHandle(const char* pkgid) {
- for (auto& reader : readers_) {
- if (!reader.Init()) {
- LOGE("reader.Init() fail");
- continue;
- }
- int result;
- auto handle = reader.GetHandle(pkgid, &result);
+ for (auto reader : readers_) {
+ ShmError result;
+ auto handle = reader->GetHandle(pkgid, &result);
if (handle)
return handle;
}
ShmPkgReader::ShmPkgReader(uid_t uid) {
readers_.emplace_back(
- ShmNameProvider::PkgConfig(uid),
- ShmNameProvider::PkgHandle(uid),
- ShmNameProvider::PkgIndexs(uid),
- ShmNameProvider::PkgKeys(uid));
+ ShmPkgReader::ShmPkgReaderProvider::GetReader(uid));
if (uid > REGULAR_USER)
readers_.emplace_back(
- ShmNameProvider::PkgConfig(GLOBAL_USER),
- ShmNameProvider::PkgHandle(GLOBAL_USER),
- ShmNameProvider::PkgIndexs(GLOBAL_USER),
- ShmNameProvider::PkgKeys(GLOBAL_USER));
-}
-
-bool ShmPkgReader::Init() {
- if (_is_writer()) {
- LOGD("process(%d) is writer", getpid());
- return false;
- }
-
- for (auto& reader : readers_) {
- if (!reader.Init()) {
- LOGE("Init reader fail");
- return false;
- }
- }
-
- return true;
+ ShmPkgReader::ShmPkgReaderProvider::GetReader(GLOBAL_USER));
}
bool ShmPkgReader::FilterChecker::Init(pkgmgrinfo_filter_x* filter) {
return pkgid_filter_;
}
+ShmReader<PkgInfoHandle>*
+ ShmPkgReader::ShmPkgReaderProvider::GetReader(uid_t uid) {
+ static std::shared_mutex lock_;
+ std::shared_lock<std::shared_mutex> s(lock_);
+
+ uid = ConvertUID(uid);
+ auto it = readers_map_.find(uid);
+ if (it != readers_map_.end())
+ return it->second;
+
+ s.unlock();
+ std::unique_lock<std::shared_mutex> u(lock_);
+ auto* prov = readers_map_[uid];
+ if (prov == nullptr)
+ readers_map_[uid] =
+ new ShmReader<PkgInfoHandle>(PKG_SHM_PREFIX + std::to_string(uid));
+
+ return readers_map_[uid];
+}
+
} // namespace shared_memory
} // namespace pkgmgr_common
public:
ShmPkgReader(uid_t uid);
- bool Init();
int GetHandles(pkgmgrinfo_filter_x* filter,
std::map<std::string, PkgInfoHandle>& list);
std::optional<PkgInfoHandle> GetHandle(const char* pkgid);
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_;
+ std::vector<ShmReader<PkgInfoHandle>*> readers_;
};
} // namespace shared_memory
namespace shared_memory {
template<typename T>
-bool ShmReader<T>::Init() {
- if (!config_handler_.Load()) {
- LOGE("Failed to load config handler");
- return false;
+std::optional<ShmLockGuard> ShmReader<T>::Load(ShmError* result,
+ std::shared_lock<std::shared_mutex>& s) {
+ *result = config_handler_.Load();
+ if (*result != ShmError::NONE)
+ return std::nullopt;
+
+ if (!config_handler_.GetIsValid()) {
+ do {
+ LOGW("config is not valid, reload");
+ s.unlock();
+ std::unique_lock<std::shared_mutex> u(lock_);
+ if (config_handler_.GetIsValid()) {
+ u.unlock();
+ s.lock();
+ break;
+ }
+
+ ShmError ret = ShmError::NONE;
+ ret = config_handler_.Unload();
+ if (ret != ShmError::NONE)
+ LOGE("config_handler_.Unload() fail");
+
+ ret = handle_mapper_.Unload();
+ if (ret != ShmError::NONE)
+ LOGE("handle_mapper_.Unload() fail");
+
+ ret = index_mapper_.Unload();
+ if (ret != ShmError::NONE)
+ LOGE("index_mapper_.Unload() fail");
+
+ ret = key_mapper_.Unload();
+ if (ret != ShmError::NONE)
+ LOGE("key_mapper_.Unload() fail");
+
+ if (ret != ShmError::NONE) {
+ *result = ret;
+ return std::nullopt;
+ }
+
+ ret = config_handler_.Load();
+ if (ret != ShmError::NONE) {
+ *result = ret;
+ return std::nullopt;
+ }
+
+ u.unlock();
+ s.lock();
+
+ if (!config_handler_.GetIsValid()) {
+ LOGW("config is not valid, reload");
+ *result = ShmError::SYSTEM;
+ return std::nullopt;
+ }
+ } while (0);
+ }
+
+ auto read_lock = config_handler_.GetReadLock();
+ if (!read_lock) {
+ LOGE("Fail to get read lock");
+ *result = ShmError::READ_LOCK;
+ return std::nullopt;
+ }
+
+ *result = handle_mapper_.LoadAll();
+ if (*result != ShmError::NONE) {
+ LOGE("Failed to load handle");
+ return std::nullopt;
}
- int ret = config_handler_.GetReadLock();
- if (ret != 0) {
- LOGE("Fail to get read lock, %d", ret);
- return false;
+ *result = index_mapper_.LoadAll();
+ if (*result != ShmError::NONE) {
+ LOGE("Failed to load index");
+ return std::nullopt;
}
- auto indexs = ReadIndexs();
- if (!indexs) {
- LOGE("Failed to get pkg indexs");
- return false;
+ *result = key_mapper_.LoadAll();
+ if (*result != ShmError::NONE) {
+ LOGE("Failed to load key");
+ return std::nullopt;
}
- mapping_data_ = std::move(*indexs);
+ *result = ShmError::NONE;
- return true;
+ return read_lock;
}
template<typename T>
-std::optional<std::vector<T>> ShmReader<T>::GetHandles(int* result) {
+std::optional<std::vector<T>> ShmReader<T>::GetHandles(ShmError* result) {
+ std::shared_lock<std::shared_mutex> s(lock_);
+ auto lock = Load(result, s);
+ if (!lock)
+ return std::nullopt;
+
return ReadHandles(result);
}
template<typename T>
-std::optional<T> ShmReader<T>::GetHandle(const char* key, int* result) {
- int index = FindIndex(key, result);
- if (index < 0)
+std::optional<T> ShmReader<T>::GetHandle(const char* key, ShmError* result) {
+ std::shared_lock<std::shared_mutex> s(lock_);
+ auto lock = Load(result, s);
+ if (!lock)
+ return std::nullopt;
+
+ HandleMappingData* index_ptr = FindIndex(key, result);
+ if (!index_ptr) {
+ LOGD("Can't get index by key[%s]", key);
return std::nullopt;
+ }
- auto handle = ReadHandle(mapping_data_[index].index, mapping_data_[index].len);
+ auto handle = ReadHandle(index_ptr->index, index_ptr->len);
if (!handle) {
LOGE("Failed to read app");
- *result = TIZEN_ERROR_IO_ERROR;
+ *result = ShmError::SYSTEM;
return std::nullopt;
}
- *result = TIZEN_ERROR_NONE;
- return std::move(*handle);
+ *result = ShmError::NONE;
+ return handle;
}
template<typename T>
-std::optional<std::vector<T>> ShmReader<T>::ReadHandles(int* result) {
- if (!result)
- return std::nullopt;
- *result = TIZEN_ERROR_NONE;
-
- auto indexs = ReadIndexs();
- if (!indexs) {
- LOGE("Failed to get app indexs");
- *result = TIZEN_ERROR_IO_ERROR;
+std::optional<std::vector<T>> ShmReader<T>::ReadHandles(ShmError* result) {
+ if (!result) {
+ LOGE("Invalid parameter");
return std::nullopt;
}
- if (indexs->empty()) {
- LOGD("The app doesn't exist");
- return std::vector<T>{};
- }
-
- if(!handle_mapper_.Init()) {
- *result = TIZEN_ERROR_IO_ERROR;
- return std::nullopt;
- }
+ *result = ShmError::NONE;
- size_t mapping_len = GetMemSize();
- if(!handle_mapper_.LoadAll(mapping_len)) {
- *result = TIZEN_ERROR_IO_ERROR;
- return std::nullopt;
+ if (index_mapper_.GetMemSize() == 0) {
+ LOGD("Empty Shm Data");
+ return std::vector<T>{};
}
std::vector<T> handles;
uint8_t* ptr = handle_mapper_.GetPtr();
- for (const auto& mapping : *indexs)
- handles.emplace_back(std::make_unique<tizen_base::Parcel>(ptr + mapping.index, mapping.len, true));
+ 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));
return handles;
}
template<typename T>
std::optional<T> ShmReader<T>::ReadHandle(
uint32_t index, uint32_t len) {
- if (mapping_data_.empty()) {
- LOGD("The handle doesn't exist");
- return std::nullopt;
- }
-
- if(!handle_mapper_.Init()) {
- return std::nullopt;
- }
-
- uint8_t* ptr = handle_mapper_.CopyPartial(index, len);
- if (ptr == nullptr) {
- return std::nullopt;
- }
-
- return T(std::make_unique<tizen_base::Parcel>(ptr, len, false));
+ return T(std::make_unique<tizen_base::Parcel>(
+ handle_mapper_.GetPtr() + index, len, true));
}
template<typename T>
-std::optional<std::vector<HandleMappingData>> ShmReader<T>::ReadIndexs() {
- size_t indexs_len = GetIndexMemSize();
- if (indexs_len == 0) {
- LOGD("Empty index");
- return std::vector<HandleMappingData>{};
- }
-
- if (indexs_len % sizeof(HandleMappingData) != 0) {
- LOGE("Invalid app indexs size : %zu", indexs_len);
- return std::nullopt;
- }
- int index_count = indexs_len / sizeof(HandleMappingData);
-
- if(!index_mapper_.Init()) {
- return std::nullopt;
- }
-
- if(!index_mapper_.LoadAll(indexs_len)) {
- return std::nullopt;
- }
-
- std::vector<HandleMappingData> result;
- auto ptr = (HandleMappingData*)index_mapper_.GetPtr();
- while(index_count--) {
- result.emplace_back(HandleMappingData {
- .key_index = ptr->key_index,
- .index = ptr->index,
- .len = ptr->len
- });
- ptr++;
- }
-
- return result;
-}
-
-template<typename T>
-int ShmReader<T>::FindIndex(const char* key, int* result) {
- if (mapping_data_.empty()) {
- LOGD("The pkg doesn't exist");
- *result = TIZEN_ERROR_NO_DATA;
- return -1;
- }
-
- if(!key_mapper_.Init()) {
- *result = TIZEN_ERROR_IO_ERROR;
- return -1;
- }
-
- size_t mapping_len = GetKeyMemSize();
- if(!key_mapper_.LoadAll(mapping_len)) {
- *result = TIZEN_ERROR_IO_ERROR;
- return -1;
- }
-
- std::vector<const char*> keys;
- const char* ptr = reinterpret_cast<const char*>(key_mapper_.GetPtr());
- for (const auto& mapping : mapping_data_)
- keys.emplace_back(ptr + mapping.key_index);
+HandleMappingData* ShmReader<T>::FindIndex(const char* key, ShmError* result) {
+ const char* key_ptr = reinterpret_cast<const char*>(key_mapper_.GetPtr());
+ auto index_ptr = reinterpret_cast<HandleMappingData*>(index_mapper_.GetPtr());
int l = 0;
- int r = keys.size();
- int index = -1;
-
+ int r = index_mapper_.GetMemSize() / sizeof(HandleMappingData);
+ HandleMappingData* result_ptr = nullptr;
while (l < r) {
int mid = (l + r) / 2;
- int result = strcmp(key, keys[mid]);
- if (result == 0) {
- index = mid;
+ int cmp_result = strcmp(key, key_ptr + (index_ptr[mid].key_index));
+ if (cmp_result == 0) {
+ result_ptr = index_ptr + mid;
break;
- } else if (result < 0) {
+ } else if (cmp_result < 0) {
r = mid;
} else {
l = mid+1;
}
}
- *result = TIZEN_ERROR_NONE;
- return index;
-}
-
-template<typename T>
-size_t ShmReader<T>::GetMemSize() const {
- return config_handler_.GetMemSize();
-}
-
-template<typename T>
-size_t ShmReader<T>::GetIndexMemSize() const {
- return config_handler_.GetIndexMemSize();
-}
-
-template<typename T>
-size_t ShmReader<T>::GetKeyMemSize() const {
- return config_handler_.GetKeyMemSize();
+ *result = ShmError::NONE;
+ return result_ptr;
}
} // namespace shared_memory
#ifndef COMMON_SHM_READER_HH_
#define COMMON_SHM_READER_HH_
+#include <mutex>
#include <optional>
+#include <shared_mutex>
#include <vector>
#include "pkgmgr_info_handle.hh"
template<typename T>
class EXPORT_API ShmReader {
public:
- ShmReader(const char* config_shm_name,
- const char* handle_shm_name, const char* index_shm_name,
- const char* key_shm_name) :
- config_handler_(config_shm_name),
- handle_mapper_(handle_shm_name),
- index_mapper_(index_shm_name),
- key_mapper_(key_shm_name) {}
- bool Init();
- std::optional<std::vector<T>> GetHandles(int* result);
- std::optional<T> GetHandle(const char* key, int* result);
+ 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"),
+ key_mapper_(base_name_ + "_keys") {}
+ std::optional<std::vector<T>> GetHandles(ShmError* result);
+ std::optional<T> GetHandle(const char* key, ShmError* result);
private:
- std::optional<std::vector<HandleMappingData>> ReadIndexs();
- std::optional<std::vector<T>> ReadHandles(int* result);
+ std::optional<ShmLockGuard> Load(ShmError* result,
+ std::shared_lock<std::shared_mutex>& s);
+ std::optional<std::vector<T>> ReadHandles(ShmError* result);
std::optional<T> ReadHandle(uint32_t index, uint32_t len);
- int FindIndex(const char* key, int* result);
- size_t GetMemSize() const;
- size_t GetIndexMemSize() const;
- size_t GetKeyMemSize() const;
+ HandleMappingData* FindIndex(const char* key, ShmError* result);
protected:
- std::vector<HandleMappingData> mapping_data_;
+ std::string base_name_;
ShmConfigHandler config_handler_;
ShmReadMapper handle_mapper_;
ShmReadMapper index_mapper_;
ShmReadMapper key_mapper_;
+ std::shared_mutex lock_;
};
template class ShmReader<PkgInfoHandle>;
}
int ret = PMINFO_R_OK;
- ps::ShmAppReader reader(uid);
std::map<std::string, pc::AppInfoHandle> list;
pkgmgr_appinfo_x *info;
- if (reader.Init()) {
+ if (!_is_writer()) {
+ ps::ShmAppReader reader(uid);
ret = reader.GetHandles(reinterpret_cast<pkgmgrinfo_filter_x*>(filter), list);
+ if (ret != PMINFO_R_OK) {
+ ret = _appinfo_get_applications(uid,
+ reinterpret_cast<pkgmgrinfo_filter_x*>(filter),
+ PMINFO_APPINFO_GET_ALL, &list);
+ }
} else {
ret = _appinfo_get_applications(uid,
reinterpret_cast<pkgmgrinfo_filter_x*>(filter),
{
int ret;
pkgmgr_appinfo_x info;
- ps::ShmAppReader reader(uid);
std::map<std::string, pc::AppInfoHandle> list;
- if (reader.Init())
+
+ if (!_is_writer()) {
+ ps::ShmAppReader reader(uid);
ret = reader.GetHandles(reinterpret_cast<pkgmgrinfo_filter_x*>(filter), list);
- else
+ if (ret != PMINFO_R_OK) {
+ ret = _appinfo_get_applications(uid,
+ reinterpret_cast<pkgmgrinfo_filter_x*>(filter),
+ PMINFO_APPINFO_GET_ALL, &list);
+ }
+ } else {
ret = _appinfo_get_applications(uid,
reinterpret_cast<pkgmgrinfo_filter_x*>(filter),
PMINFO_APPINFO_GET_ALL, &list);
+ }
if (ret == PMINFO_R_ERROR)
return ret;
return PMINFO_R_ERROR;
}
- ps::ShmAppReader reader(uid);
std::map<std::string, pc::AppInfoHandle> list;
- if (reader.Init())
+ if (!_is_writer()) {
+ ps::ShmAppReader reader(uid);
ret = reader.GetHandles(reinterpret_cast<pkgmgrinfo_filter_x*>(filter), list);
- else
+ if (ret != PMINFO_R_OK) {
+ ret = _appinfo_get_applications(uid,
+ reinterpret_cast<pkgmgrinfo_filter_x*>(filter),
+ PMINFO_APPINFO_GET_ALL, &list);
+ }
+ } else {
ret = _appinfo_get_applications(uid,
reinterpret_cast<pkgmgrinfo_filter_x*>(filter),
- 0, &list);
+ PMINFO_APPINFO_GET_ALL, &list);
+ }
if (ret == PMINFO_R_ERROR)
return ret;
pkgmgrinfo_pkg_list_cb pkg_list_cb, void *user_data)
{
int ret;
- ps::ShmPkgReader reader(uid);
std::map<std::string, pc::PkgInfoHandle> list;
pkgmgr_pkginfo_x info;
return PMINFO_R_ERROR;
}
}
- if (reader.Init())
+
+ if (!_is_writer()) {
+ ps::ShmPkgReader reader(uid);
ret = reader.GetHandles(reinterpret_cast<pkgmgrinfo_filter_x*>(filter), list);
- else
+ if (ret != PMINFO_R_OK) {
+ ret = _pkginfo_get_packages(uid,
+ reinterpret_cast<pkgmgrinfo_filter_x*>(filter),
+ PMINFO_PKGINFO_GET_ALL, &list);
+ }
+ } else {
ret = _pkginfo_get_packages(uid,
reinterpret_cast<pkgmgrinfo_filter_x*>(filter),
PMINFO_PKGINFO_GET_ALL, &list);
+ }
if (ret == PMINFO_R_ERROR)
return ret;
}
int ret;
- ps::ShmPkgReader reader(uid);
std::map<std::string, pc::PkgInfoHandle> list;
- if (reader.Init()) {
+ if (!_is_writer()) {
+ ps::ShmPkgReader reader(uid);
ret = reader.GetHandles(reinterpret_cast<pkgmgrinfo_filter_x*>(filter), list);
+ if (ret != PMINFO_R_OK) {
+ ret = _pkginfo_get_packages(uid,
+ reinterpret_cast<pkgmgrinfo_filter_x*>(filter),
+ PMINFO_PKGINFO_GET_ALL, &list);
+ }
} else {
ret = _pkginfo_get_packages(uid,
reinterpret_cast<pkgmgrinfo_filter_x*>(filter),
API int pkgmgrinfo_pkginfo_usr_filter_count(pkgmgrinfo_pkginfo_filter_h filter, int *count, uid_t uid)
{
int ret;
- ps::ShmPkgReader reader(uid);
std::map<std::string, pc::PkgInfoHandle> list;
if (filter == NULL || count == NULL) {
return PMINFO_R_ERROR;
}
- if (reader.Init())
+ if (!_is_writer()) {
+ ps::ShmPkgReader reader(uid);
ret = reader.GetHandles(reinterpret_cast<pkgmgrinfo_filter_x*>(filter), list);
- else
+ if (ret != PMINFO_R_OK) {
+ ret = _pkginfo_get_packages(uid,
+ reinterpret_cast<pkgmgrinfo_filter_x*>(filter),
+ PMINFO_PKGINFO_GET_ALL, &list);
+ }
+ } else {
ret = _pkginfo_get_packages(uid,
reinterpret_cast<pkgmgrinfo_filter_x*>(filter),
PMINFO_PKGINFO_GET_ALL, &list);
+ }
if (ret == PMINFO_R_ERROR)
return ret;
*count = list.size();
namespace {
-char* GetCString(int idx, const tizen_base::Database::Result::Record& rec) {
- std::optional<std::string> str = rec.GetString(idx);
- if (!str)
- return nullptr;
-
- return strdup(str->c_str());
-}
-
-const char* GetCString2(int idx, const tizen_base::Database::Result::Record& rec) {
+const char* GetCString(int idx, const tizen_base::Database::Result::Record& rec) {
return rec.GetCString(idx);
}
auto& list_writer = writer.GetSplashscreensListWriter();
for (const auto& rec : r) {
list_writer.AddItem()
- .WriteSrc(GetCString2(0, rec))
- .WriteType(GetCString2(1, rec))
- .WriteOrientation(GetCString2(2, rec))
- .WriteIndicatordisplay(GetCString2(3, rec))
- .WriteOperation(GetCString2(4, rec))
- .WriteColorDepth(GetCString2(5, rec));
+ .WriteSrc(GetCString(0, rec))
+ .WriteType(GetCString(1, rec))
+ .WriteOrientation(GetCString(2, rec))
+ .WriteIndicatordisplay(GetCString(3, rec))
+ .WriteOperation(GetCString(4, rec))
+ .WriteColorDepth(GetCString(5, rec));
}
return PMINFO_R_OK;
_LOGE("db.Exec() failed: %s", static_cast<const char*>(r));
for (const auto& rec : r) {
- const char* val = GetCString2(0, rec);
+ const char* val = GetCString(0, rec);
if (val)
writer.Write(val);
}
auto& list_writer = writer.GetMetadataListWriter();
for (const auto& rec : r) {
list_writer.AddItem()
- .WriteKey(GetCString2(0, rec))
- .WriteValue(GetCString2(1, rec));
+ .WriteKey(GetCString(0, rec))
+ .WriteValue(GetCString(1, rec));
}
return PMINFO_R_OK;
}
for (const auto& rec : r) {
- ParseAppControl(db, writer, GetCString2(0, rec),
- GetCString2(1, rec), GetCString2(2, rec), appid);
+ ParseAppControl(db, writer, GetCString(0, rec),
+ GetCString(1, rec), GetCString(2, rec), appid);
}
return PMINFO_R_OK;
auto& list_writer = writer.GetCategoryListWriter();
for (const auto& rec : r) {
- const char* val = GetCString2(0, rec);
+ const char* val = GetCString(0, rec);
if (val)
list_writer.Write(val);
}
auto& list_writer = writer.GetResControlListWriter();
for (const auto& rec : r) {
list_writer.AddItem()
- .WriteResType(GetCString2(0, rec))
- .WriteMinResVersion(GetCString2(1, rec))
- .WriteMaxResVersion(GetCString2(2, rec))
- .WriteAutoClose(GetCString2(3, rec));
+ .WriteResType(GetCString(0, rec))
+ .WriteMinResVersion(GetCString(1, rec))
+ .WriteMaxResVersion(GetCString(2, rec))
+ .WriteAutoClose(GetCString(3, rec));
}
return PMINFO_R_OK;
const char* is_disabled = nullptr;
const char* splash_screen_display = nullptr;
- writer.WriteAppId(appid = GetCString2(idx++, rec));
- writer.WriteInstalledStorage(installed_storage = GetCString2(idx++, rec));
- writer.WriteExternalPath(external_path = GetCString2(idx++, rec));
- is_disabled = GetCString2(idx++, rec);
+ writer.WriteAppId(appid = GetCString(idx++, rec));
+ writer.WriteInstalledStorage(installed_storage = GetCString(idx++, rec));
+ writer.WriteExternalPath(external_path = GetCString(idx++, rec));
+ is_disabled = GetCString(idx++, rec);
if (flag & PMINFO_APPINFO_GET_BASICINFO) {
writer.WriteIsDisabled(is_disabled);
- writer.WriteComponent(GetCString2(idx++, rec));
- writer.WriteExec(GetCString2(idx++, rec));
- writer.WriteNodisplay(GetCString2(idx++, rec));
- writer.WriteType(GetCString2(idx++, rec));
- writer.WriteOnboot(GetCString2(idx++, rec));
- writer.WriteMultiple(GetCString2(idx++, rec));
- writer.WriteAutoRestart(GetCString2(idx++, rec));
- writer.WriteTaskManage(GetCString2(idx++, rec));
- writer.WriteHwAcceleration(GetCString2(idx++, rec));
- writer.WriteScreenReader(GetCString2(idx++, rec));
- writer.WriteMainApp(GetCString2(idx++, rec));
- writer.WriteRecentimage(GetCString2(idx++, rec));
- writer.WriteLaunchCondition(GetCString2(idx++, rec));
- writer.WriteIndicatorDisplay(GetCString2(idx++, rec));
- writer.WritePortraitImg(GetCString2(idx++, rec));
- writer.WriteLandscapeImg(GetCString2(idx++, rec));
- writer.WriteGuestModeVisibility(GetCString2(idx++, rec));
- writer.WritePermissionType(GetCString2(idx++, rec));
- writer.WritePreload(GetCString2(idx++, rec));
- writer.WriteSubmode(GetCString2(idx++, rec));
- writer.WriteSubmodeMainId(GetCString2(idx++, rec));
- writer.WriteLaunchMode(GetCString2(idx++, rec));
- writer.WriteUiGadget(GetCString2(idx++, rec));
- writer.WriteSupportDisable(GetCString2(idx++, rec));
- writer.WriteProcessPool(GetCString2(idx++, rec));
- __get_background_category(GetCString2(idx++, rec), writer);
- writer.WritePackageType(GetCString2(idx++, rec));
- writer.WriteRootPath(GetCString2(idx++, rec));
- writer.WriteApiVersion(GetCString2(idx++, rec));
- writer.WriteEffectiveAppId(GetCString2(idx++, rec));
- writer.WriteSplashScreenDisplay(splash_screen_display = GetCString2(idx++, rec));
- writer.WriteTepName(GetCString2(idx++, rec));
- writer.WriteZipMountFile(GetCString2(idx++, rec));
- writer.WriteComponentType(GetCString2(idx++, rec));
- package = GetCString2(idx++, rec);
+ writer.WriteComponent(GetCString(idx++, rec));
+ writer.WriteExec(GetCString(idx++, rec));
+ writer.WriteNodisplay(GetCString(idx++, rec));
+ writer.WriteType(GetCString(idx++, rec));
+ writer.WriteOnboot(GetCString(idx++, rec));
+ writer.WriteMultiple(GetCString(idx++, rec));
+ writer.WriteAutoRestart(GetCString(idx++, rec));
+ writer.WriteTaskManage(GetCString(idx++, rec));
+ writer.WriteHwAcceleration(GetCString(idx++, rec));
+ writer.WriteScreenReader(GetCString(idx++, rec));
+ writer.WriteMainApp(GetCString(idx++, rec));
+ writer.WriteRecentimage(GetCString(idx++, rec));
+ writer.WriteLaunchCondition(GetCString(idx++, rec));
+ writer.WriteIndicatorDisplay(GetCString(idx++, rec));
+ writer.WritePortraitImg(GetCString(idx++, rec));
+ writer.WriteLandscapeImg(GetCString(idx++, rec));
+ writer.WriteGuestModeVisibility(GetCString(idx++, rec));
+ writer.WritePermissionType(GetCString(idx++, rec));
+ writer.WritePreload(GetCString(idx++, rec));
+ writer.WriteSubmode(GetCString(idx++, rec));
+ writer.WriteSubmodeMainId(GetCString(idx++, rec));
+ writer.WriteLaunchMode(GetCString(idx++, rec));
+ writer.WriteUiGadget(GetCString(idx++, rec));
+ writer.WriteSupportDisable(GetCString(idx++, rec));
+ writer.WriteProcessPool(GetCString(idx++, rec));
+ __get_background_category(GetCString(idx++, rec), writer);
+ writer.WritePackageType(GetCString(idx++, rec));
+ writer.WriteRootPath(GetCString(idx++, rec));
+ writer.WriteApiVersion(GetCString(idx++, rec));
+ writer.WriteEffectiveAppId(GetCString(idx++, rec));
+ writer.WriteSplashScreenDisplay(splash_screen_display = GetCString(idx++, rec));
+ writer.WriteTepName(GetCString(idx++, rec));
+ writer.WriteZipMountFile(GetCString(idx++, rec));
+ writer.WriteComponentType(GetCString(idx++, rec));
+ package = GetCString(idx++, rec);
writer.WritePackage(package);
- writer.WritePackageSystem(GetCString2(idx++, rec));
- writer.WriteRemovable(GetCString2(idx++, rec));
- writer.WritePackageInstalledTime(GetCString2(idx++, rec));
- writer.WriteSupportMode(GetCString2(idx++, rec));
- writer.WriteSupportAmbient(GetCString2(idx++, rec));
- writer.WriteSetupAppId(GetCString2(idx++, rec));
- writer.WriteLightUserSwitchMode(GetCString2(idx++, rec));
+ writer.WritePackageSystem(GetCString(idx++, rec));
+ writer.WriteRemovable(GetCString(idx++, rec));
+ writer.WritePackageInstalledTime(GetCString(idx++, rec));
+ writer.WriteSupportMode(GetCString(idx++, rec));
+ writer.WriteSupportAmbient(GetCString(idx++, rec));
+ writer.WriteSetupAppId(GetCString(idx++, rec));
+ writer.WriteLightUserSwitchMode(GetCString(idx++, rec));
}
writer.WriteForAllUsers((db_uid != global_user_uid) ? "false" : "true");
if (db_uid != global_user_uid) {
idx = idx + 2;
} else {
- tmp_record = GetCString2(idx++, rec);
+ tmp_record = GetCString(idx++, rec);
if (tmp_record != nullptr) {
if (is_disabled &&
strcasecmp(is_disabled, "false") == 0 &&
strcasecmp(tmp_record, "false") == 0)
writer.WriteIsDisabled(tmp_record);
}
- tmp_record = GetCString2(idx++, rec);
+ tmp_record = GetCString(idx++, rec);
if (tmp_record != nullptr) {
if (splash_screen_display &&
strcasecmp(splash_screen_display, "false") == 0 &&
if (flag & PMINFO_APPINFO_GET_LABEL) {
auto& list_writer = writer.GetLabelListWriter();
list_writer.AddItem()
- .WriteText(GetCString2(idx++, rec))
+ .WriteText(GetCString(idx++, rec))
.WriteLang(locale);
}
if (flag & PMINFO_APPINFO_GET_ICON) {
auto& list_writer = writer.GetIconListWriter();
list_writer.AddItem()
- .WriteText(GetCString2(idx++, rec))
+ .WriteText(GetCString(idx++, rec))
.WriteLang(locale);
}
- tmp_record = GetCString2(idx++, rec);
+ tmp_record = GetCString(idx++, rec);
if (tmp_record) {
writer.WriteIsPackageDisabled(tmp_record);
if (pkg_disable_filter_status != PackageDisableFilterStatus::None) {
" LEFT OUTER JOIN package_metadata"
" ON pi.package=package_metadata.package";
-char* GetCString(int idx, const tizen_base::Database::Result::Record& rec) {
+char* GetAllocatedCString(int idx,
+ const tizen_base::Database::Result::Record& rec) {
std::optional<std::string> str = rec.GetString(idx);
if (!str)
return nullptr;
return strdup(str->c_str());
}
-const char* GetCString2(int idx, const tizen_base::Database::Result::Record& rec) {
+const char* GetCString(int idx, const tizen_base::Database::Result::Record& rec) {
return rec.GetCString(idx);
}
auto& plugin_writer = writer.GetPluginListWriter();
for (const auto& rec : r) {
plugin_writer.AddItem()
- .WritePkgid(GetCString2(0, rec))
- .WriteAppid(GetCString2(1, rec))
- .WritePluginType(GetCString2(2, rec))
- .WritePluginName(GetCString2(3, rec));
+ .WritePkgid(GetCString(0, rec))
+ .WriteAppid(GetCString(1, rec))
+ .WritePluginType(GetCString(2, rec))
+ .WritePluginName(GetCString(3, rec));
}
return PMINFO_R_OK;
auto& privilege_list_writer = writer.GetPrivilegesListWriter();
for (const auto& rec : r) {
privilege_list_writer.AddItem()
- .WriteValue(GetCString2(0, rec))
- .WriteType(GetCString2(1, rec));
+ .WriteValue(GetCString(0, rec))
+ .WriteType(GetCString(1, rec));
}
return PMINFO_R_OK;
auto& privilege_writer = writer.GetAppdefinedPrivilegesListWriter();
for (const auto& rec : r) {
privilege_writer.AddItem()
- .WriteType(GetCString2(2, rec))
- .WriteValue(GetCString2(0, rec))
- .WriteLicense(GetCString2(1, rec));
+ .WriteType(GetCString(2, rec))
+ .WriteValue(GetCString(0, rec))
+ .WriteLicense(GetCString(1, rec));
}
return PMINFO_R_OK;
auto& dependency_writer = writer.GetDependenciesListWriter();
for (const auto& rec : r) {
dependency_writer.AddItem()
- .WriteDependsOn(GetCString2(0, rec))
- .WriteType(GetCString2(1, rec))
- .WriteRequiredVersion(GetCString2(2, rec));
+ .WriteDependsOn(GetCString(0, rec))
+ .WriteType(GetCString(1, rec))
+ .WriteRequiredVersion(GetCString(2, rec));
}
return PMINFO_R_OK;
const char* package = nullptr;
const char* privilege = nullptr;
- package = GetCString2(0, rec);
+ package = GetCString(0, rec);
if (!package)
continue;
auto& required_privileges = allowed_packages_map[package];
- privilege = GetCString2(1, rec);
+ privilege = GetCString(1, rec);
if (!privilege)
continue;
if (GetResAllowedPackages(db, pkgid, writer) != PMINFO_R_OK)
return PMINFO_R_ERROR;
- writer.WriteResType(GetCString2(0, *rec));
- writer.WriteResVersion(GetCString2(1, *rec));
- writer.WriteLib(GetCString2(2, *rec));
+ writer.WriteResType(GetCString(0, *rec));
+ writer.WriteResVersion(GetCString(1, *rec));
+ writer.WriteLib(GetCString(2, *rec));
return PMINFO_R_OK;
}
auto& metadata_writer = writer.GetMetadataListWriter();
for (const auto& rec : r) {
metadata_writer.AddItem()
- .WriteKey(GetCString2(0, rec))
- .WriteValue(GetCString2(1, rec));
+ .WriteKey(GetCString(0, rec))
+ .WriteValue(GetCString(1, rec));
}
return PMINFO_R_OK;
const char* installed_storage = nullptr;
const char* external_path = nullptr;
const char* is_disabled = nullptr;
- writer.WritePackage(package = GetCString2(idx++, rec));
- writer.WriteInstalledStorage(installed_storage = GetCString2(idx++, rec));
- writer.WriteExternalPath(external_path = GetCString2(idx++, rec));
- is_disabled = GetCString2(idx++, rec);
+ writer.WritePackage(package = GetCString(idx++, rec));
+ writer.WriteInstalledStorage(installed_storage = GetCString(idx++, rec));
+ writer.WriteExternalPath(external_path = GetCString(idx++, rec));
+ is_disabled = GetCString(idx++, rec);
if (flag & PMINFO_APPINFO_GET_BASICINFO) {
writer.WriteIsDisabled(is_disabled);
- writer.WriteVersion(GetCString2(idx++, rec));
- writer.WriteInstallLocation(GetCString2(idx++, rec));
- writer.WriteRemovable(GetCString2(idx++, rec));
- writer.WritePreload(GetCString2(idx++, rec));
- writer.WriteReadonly(GetCString2(idx++, rec));
- writer.WriteUpdate(GetCString2(idx++, rec));
- writer.WriteAppSetting(GetCString2(idx++, rec));
- writer.WriteSystem(GetCString2(idx++, rec));
- writer.WriteType(GetCString2(idx++, rec));
- writer.WritePackageSize(GetCString2(idx++, rec));
- writer.WriteInstalledTime(GetCString2(idx++, rec));
- writer.WriteStoreClientId(GetCString2(idx++, rec));
- writer.WriteMainAppId(GetCString2(idx++, rec));
- writer.WritePackageUrl(GetCString2(idx++, rec));
- writer.WriteRootPath(GetCString2(idx++, rec));
- writer.WriteCscPath(GetCString2(idx++, rec));
- writer.WriteNoDisplaySetting(GetCString2(idx++, rec));
- writer.WriteApiVersion(GetCString2(idx++, rec));
- writer.WriteSupportDisable(GetCString2(idx++, rec));
- writer.WriteTepName(GetCString2(idx++, rec));
- writer.WriteZipMountFile(GetCString2(idx++, rec));
- writer.WriteSupportMode(GetCString2(idx++, rec));
- writer.WriteLightUserSwitchMode(GetCString2(idx++, rec));
+ writer.WriteVersion(GetCString(idx++, rec));
+ writer.WriteInstallLocation(GetCString(idx++, rec));
+ writer.WriteRemovable(GetCString(idx++, rec));
+ writer.WritePreload(GetCString(idx++, rec));
+ writer.WriteReadonly(GetCString(idx++, rec));
+ writer.WriteUpdate(GetCString(idx++, rec));
+ writer.WriteAppSetting(GetCString(idx++, rec));
+ writer.WriteSystem(GetCString(idx++, rec));
+ writer.WriteType(GetCString(idx++, rec));
+ writer.WritePackageSize(GetCString(idx++, rec));
+ writer.WriteInstalledTime(GetCString(idx++, rec));
+ writer.WriteStoreClientId(GetCString(idx++, rec));
+ writer.WriteMainAppId(GetCString(idx++, rec));
+ writer.WritePackageUrl(GetCString(idx++, rec));
+ writer.WriteRootPath(GetCString(idx++, rec));
+ writer.WriteCscPath(GetCString(idx++, rec));
+ writer.WriteNoDisplaySetting(GetCString(idx++, rec));
+ writer.WriteApiVersion(GetCString(idx++, rec));
+ writer.WriteSupportDisable(GetCString(idx++, rec));
+ writer.WriteTepName(GetCString(idx++, rec));
+ writer.WriteZipMountFile(GetCString(idx++, rec));
+ writer.WriteSupportMode(GetCString(idx++, rec));
+ writer.WriteLightUserSwitchMode(GetCString(idx++, rec));
}
writer.WriteForAllUsers((uid != global_user_uid) ? "false" : "true");
if (flag & PMINFO_PKGINFO_GET_AUTHOR) {
auto& author_list_writer = writer.GetAuthorListWriter();
author_list_writer.AddItem()
- .WriteText(GetCString2(idx, rec))
- .WriteEmail(GetCString2(idx + 1, rec))
- .WriteHref(GetCString2(idx + 2, rec));
+ .WriteText(GetCString(idx, rec))
+ .WriteEmail(GetCString(idx + 1, rec))
+ .WriteHref(GetCString(idx + 2, rec));
idx += 3;
}
if (flag & PMINFO_PKGINFO_GET_LABEL) {
auto& label_list_writer = writer.GetLabelListWriter();
label_list_writer.AddItem()
- .WriteText(GetCString2(idx++, rec))
+ .WriteText(GetCString(idx++, rec))
.WriteLang(locale.c_str());
}
if (flag & PMINFO_PKGINFO_GET_ICON) {
auto& icon_list_writer = writer.GetIconListWriter();
icon_list_writer.AddItem()
- .WriteText(GetCString2(idx++, rec))
+ .WriteText(GetCString(idx++, rec))
.WriteLang(locale.c_str());
}
if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) {
auto& description_writer = writer.GetDescriptionListWriter();
description_writer.AddItem()
- .WriteText(GetCString2(idx++, rec))
+ .WriteText(GetCString(idx++, rec))
.WriteLang(locale.c_str());
}
return PMINFO_R_ERROR;
}
- req->pkgid = GetCString(0, rec);
- req->depends_on = GetCString(1, rec);
- req->type = GetCString(2, rec);
- req->required_version = GetCString(3, rec);
+ req->pkgid = GetAllocatedCString(0, rec);
+ req->depends_on = GetAllocatedCString(1, rec);
+ req->type = GetAllocatedCString(2, rec);
+ req->required_version = GetAllocatedCString(3, rec);
dep_list.push_back(req);
queue.push(req->pkgid);
namespace pkgmgr_server {
namespace shared_memory {
+static const std::string PKG_SHM_PREFIX = ".pkgmgr_info_pkg_";
+static const std::string APP_SHM_PREFIX = ".pkgmgr_info_app_";
+
std::unordered_map<uid_t, std::unique_ptr<ShmManager>>
ShmManager::shm_manager_map_;
std::unordered_set<pid_t> ShmManager::writer_pid_list_;
std::shared_mutex ShmManager::pid_list_lock_;
ShmManager::ShmManager(uid_t uid) : uid_(uid),
- pkg_writer_(
- ps::ShmNameProvider::PkgConfig(uid),
- ps::ShmNameProvider::PkgHandle(uid),
- ps::ShmNameProvider::PkgIndexs(uid),
- ps::ShmNameProvider::PkgKeys(uid)
- ),
- app_writer_(
- ps::ShmNameProvider::AppConfig(uid),
- ps::ShmNameProvider::AppHandle(uid),
- ps::ShmNameProvider::AppIndexs(uid),
- ps::ShmNameProvider::AppKeys(uid)
- ) {}
+ pkg_writer_(PKG_SHM_PREFIX + std::to_string((uid))),
+ app_writer_(APP_SHM_PREFIX + std::to_string((uid))) {}
ShmManager& ShmManager::GetInst(uid_t uid) {
static std::shared_mutex singleton_lock_;
LOG(ERROR) << "Process is crashed : " << pid;
remove_pids.emplace(pid);
} else {
+ LOGW("close fd(%d)", fd);
close(fd);
}
}
auto a_lock = app_writer_.GetLock();
for (const auto& pkgid : pkgids) {
+ LOG(WARNING) << "try to find pending package : " << pkgid;
auto pkg_it = pending_pkg_.find(pkgid);
if (pkg_it == pending_pkg_.end())
continue;
void ShmManager::ReleaseCache() {
LOGD("ReleaseCache");
pending_pkg_.clear();
+ pkg_app_map_.clear();
+ pkg_writer_.ClearSharedMemory();
+ app_writer_.ClearSharedMemory();
released_ = true;
}
template<typename T>
bool ShmWriter<T>::Init() {
- if (!config_handler_.Create()) {
+ if (config_handler_.Create() != ps::ShmError::NONE) {
LOGE("Failed to create config handler");
return false;
}
bool ShmWriter<T>::CreateSharedMemory(const std::vector<T>& handles) {
WriteHandles(handles);
- config_handler_.SetMemSize(handle_mapper_.GetSize());
- config_handler_.SetIndexMemSize(index_mapper_.GetSize());
- config_handler_.SetKeyMemSize(key_mapper_.GetSize());
+ config_handler_.SetIsValid(true);
- if (config_handler_.Unlock() != 0)
- LOGE("Failed to unlock of config writer");
+ LOGW("handle(%zu) index(%zu) key(%zu)", handle_mapper_.GetMemSize(),
+ index_mapper_.GetMemSize(), key_mapper_.GetMemSize());
return true;
}
}
LOGD("handle_mem_size : %zu", handle_mem_size);
- if (!handle_mapper_.Init(handle_mem_size)) {
+ if (handle_mapper_.Init(handle_mem_size) != ps::ShmError::NONE) {
LOGE("handle_mapper_ init fail");
return false;
}
- if (!key_mapper_.Init(key_mem_size)) {
+ if (key_mapper_.Init(key_mem_size) != ps::ShmError::NONE) {
LOGE("key_mapper_ init fail");
return false;
}
for (size_t i = 0; i < handles.size(); ++i) {
WriteKey(handles[i].GetKey(), key_sizes[i], key_index);
WriteHandle(handles[i], index);
+ LOGD("inserted handle (%d, %d, %u, %s, %s)", key_index, index,
+ handles[i].GetDataSize(), handles[i].GetKey(), base_name_.c_str());
+
indexs.emplace_back(ps::HandleMappingData {
.key_index = static_cast<uint32_t>(key_index),
.index = static_cast<uint32_t>(index),
return true;
}
- LOGD("Erase key %s, index : %d, key_index : %d", key.c_str(), index, key_index);
+ LOGD("Erase key %s, handle_index : %d, key_index : %d",
+ key.c_str(), index, key_index);
if (!RemoveKey(key_index)) {
LOGE("Failed to remove key");
return InsertHandle(handle, index, key_index);
}
+template<typename T>
+bool ShmWriter<T>::ClearSharedMemory() {
+ bool ret = true;
+
+ handle_version_ = 0;
+ index_version_ = 0;
+ key_version_ = 0;
+
+ config_handler_.SetIsValid(false);
+ if (config_handler_.Clear() != ps::ShmError::NONE)
+ ret = false;
+ if (handle_mapper_.Clear() != ps::ShmError::NONE)
+ ret = false;
+ if (index_mapper_.Clear() != ps::ShmError::NONE)
+ ret = false;
+ if (key_mapper_.Clear() != ps::ShmError::NONE)
+ ret = false;
+
+ return ret;
+}
+
template<typename T>
bool ShmWriter<T>::WriteIndexs(
const std::vector<ps::HandleMappingData>& indexs) {
size_t mem_size = sizeof(ps::HandleMappingData) * indexs.size();
- if (!index_mapper_.Init(mem_size)) {
+ if (index_mapper_.Init(mem_size) != ps::ShmError::NONE) {
LOGE("index_mapper_ init fail");
return false;
}
while (l < r) {
int mid = (l + r) / 2;
- const char* key_ptr = reinterpret_cast<const char*>(key_mapper_.GetPtr() + ptr[mid].key_index);
+ const char* key_ptr = reinterpret_cast<const char*>(
+ key_mapper_.GetPtr() + ptr[mid].key_index);
int result = strcmp(key, key_ptr);
if (result == 0) {
LOGE("The package[%s] to insert already exists", key);
}
}
- if (l == static_cast<int>(GetHandleSize())) {
- return std::make_pair(l, key_mapper_.GetSize());
- }
+ if (l == static_cast<int>(GetHandleSize()))
+ return std::make_pair(l, key_mapper_.GetMemSize());
return std::make_pair(l, ptr[l].key_index);
}
moved_num * sizeof(ps::HandleMappingData));
index_mapper_.Resize(
- index_mapper_.GetSize() - sizeof(ps::HandleMappingData));
- config_handler_.SetIndexMemSize(index_mapper_.GetSize());
+ index_mapper_.GetMemSize() - sizeof(ps::HandleMappingData));
// Resize may change real ptr
ptr = reinterpret_cast<ps::HandleMappingData*>(index_mapper_.GetPtr());
}
const char* ptr = reinterpret_cast<const char*>(key_mapper_.GetPtr());
- size_t handle_size = key_mapper_.GetSize();
- LOGE("remove key : %s", ptr + index);
+ size_t handle_size = key_mapper_.GetMemSize();
size_t key_size = strlen(ptr + index) + 1;
size_t moved_num = handle_size - index - key_size;
if (moved_num > 0)
memmove((void*)(ptr + index), (void*)(ptr + index + key_size), moved_num);
- LOGE("key_mapper size from : %zu", key_mapper_.GetSize());
+ LOGE("key_mapper size from : %zu", key_mapper_.GetMemSize());
key_mapper_.Resize(
- key_mapper_.GetSize() - key_size);
- config_handler_.SetKeyMemSize(key_mapper_.GetSize());
- LOGE("key_mapper size to : %zu", key_mapper_.GetSize());
+ key_mapper_.GetMemSize() - key_size);
+ LOGE("key_mapper size to : %zu", key_mapper_.GetMemSize());
return true;
}
return false;
}
- int insert_index = PrepareHandleSpace(handle.GetDataSize());
- if (index < 0) {
+ int handle_insert_index = PrepareHandleSpace(handle.GetDataSize());
+ if (handle_insert_index < 0) {
LOGE("Failed to prepare handle space");
return false;
}
ps::HandleMappingData data {
.key_index = static_cast<uint32_t>(key_index),
- .index = static_cast<uint32_t>(insert_index),
+ .index = static_cast<uint32_t>(handle_insert_index),
.len = handle.GetDataSize(),
};
if (!InsertIndex(data, index, strlen(handle.GetKey()) + 1)) {
return false;
}
- WriteHandle(handle, insert_index);
+ WriteHandle(handle, handle_insert_index);
+
+ LOGD("inserted handle (%d, %d, %u, %s, %s)", key_index, index,
+ handle.GetDataSize(), handle.GetKey(), base_name_.c_str());
return true;
}
template<typename T>
-bool ShmWriter<T>::InsertIndex(const ps::HandleMappingData& data, size_t index, size_t key_size) {
- LOGD("index : %zu", index);
+bool ShmWriter<T>::InsertIndex(const ps::HandleMappingData& data,
+ size_t index, size_t key_size) {
int moved_num = GetHandleSize() - index;
- if (!index_mapper_.Resize(index_mapper_.GetSize() + sizeof(ps::HandleMappingData))) {
+ if (index_mapper_.Resize(
+ index_mapper_.GetMemSize() + sizeof(ps::HandleMappingData)) !=
+ ps::ShmError::NONE) {
LOGE("Failed to resize index mapper");
return false;
}
- config_handler_.SetIndexMemSize(index_mapper_.GetSize());
auto* ptr = (ps::HandleMappingData*)index_mapper_.GetPtr();
if (moved_num > 0)
- memmove((void*)&ptr[index + 1], (void*)&ptr[index], moved_num * sizeof(ps::HandleMappingData));
+ memmove((void*)&ptr[index + 1], (void*)&ptr[index],
+ moved_num * sizeof(ps::HandleMappingData));
for (size_t i = index + 1; i < GetHandleSize(); ++i)
ptr[i].key_index += key_size;
bool ShmWriter<T>::InsertKey(const char* key, int index) {
char* ptr = reinterpret_cast<char*>(key_mapper_.GetPtr());
size_t key_size = strlen(key) + 1;
- LOGE("insert key %s", ptr + index);
- LOGE("key size : %zu\n", key_size);
- int moved_num = key_mapper_.GetSize() - index;
- if (!key_mapper_.Resize(key_mapper_.GetSize() + key_size)) {
+ int moved_num = key_mapper_.GetMemSize() - index;
+ if (key_mapper_.Resize(key_mapper_.GetMemSize() + key_size)
+ != ps::ShmError::NONE) {
LOGE("Failed to resize index mapper");
return false;
}
- config_handler_.SetKeyMemSize(key_mapper_.GetSize());
// Resize may change real ptr
ptr = reinterpret_cast<char*>(key_mapper_.GetPtr());
return result;
}
- LOGD("need to resize handle");
- int result = handle_mapper_.GetSize();
- if (!handle_mapper_.Resize(handle_mapper_.GetSize() + size)) {
+ int result = handle_mapper_.GetMemSize();
+ if (handle_mapper_.Resize(handle_mapper_.GetMemSize() + size)
+ != ps::ShmError::NONE) {
LOGE("Failed to resize handle mapper");
return -1;
}
- config_handler_.SetMemSize(handle_mapper_.GetSize());
- LOGD("handle size from[%d] to [%zu]", result, handle_mapper_.GetSize());
+ LOGD("handle size from[%d] to [%zu]", result, handle_mapper_.GetMemSize());
return result;
}
template<typename T>
size_t ShmWriter<T>::GetHandleSize() const {
- return index_mapper_.GetSize() / sizeof(ps::HandleMappingData);
+ return index_mapper_.GetMemSize() / sizeof(ps::HandleMappingData);
}
template<typename T>
-LockGuard ShmWriter<T>::GetLock() {
- return LockGuard(config_handler_);
+std::optional<ps::ShmLockGuard> ShmWriter<T>::GetLock() {
+ return config_handler_.GetWriteLock();
}
} // namespace shared_memory
namespace pc = pkgmgr_common;
namespace ps = pkgmgr_common::shared_memory;
-class LockGuard {
- public:
- LockGuard(ps::ShmConfigHandler& config_handler) : config_handler_(config_handler) {
- config_handler_.GetWriteLock();
- }
-
- ~LockGuard() {
- config_handler_.Unlock();
- }
-
- private:
- ps::ShmConfigHandler& config_handler_;
-};
-
template <typename T>
class ShmWriter {
public:
- ShmWriter(const char* config_shm_name,
- const char* handle_shm_name, const char* index_shm_name,
- const char* key_shm_name) :
- config_handler_(config_shm_name),
- handle_mapper_(handle_shm_name),
- index_mapper_(index_shm_name),
- key_mapper_(key_shm_name) {}
+ ShmWriter(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"),
+ key_mapper_(base_name_ + "_keys"),
+ handle_version_(0),
+ index_version_(0),
+ key_version_(0) {}
bool Init();
bool CreateSharedMemory(const std::vector<T>& handles);
bool Erase(const std::string& key);
bool Insert(const T& handle);
- LockGuard GetLock();
+ bool ClearSharedMemory();
+ std::optional<ps::ShmLockGuard> GetLock();
private:
bool WriteHandles(const std::vector<T>& handles);
std::pair<int, int> GetHandleInsertIndex(const char* pkgid) const;
size_t GetHandleSize() const;
+ std::string base_name_;
ps::ShmConfigHandler config_handler_;
ps::ShmWriteMapper handle_mapper_;
ps::ShmWriteMapper index_mapper_;
ps::ShmWriteMapper key_mapper_;
+ size_t handle_version_;
+ size_t index_version_;
+ size_t key_version_;
+
std::set<std::pair<size_t, size_t>> free_space_;
};