diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/GpgContext.cpp | 4 | ||||
-rw-r--r-- | src/core/GpgContext.h | 4 | ||||
-rw-r--r-- | src/core/GpgCoreInit.cpp | 17 | ||||
-rw-r--r-- | src/core/GpgFunctionObject.cpp | 143 | ||||
-rw-r--r-- | src/core/GpgFunctionObject.h | 279 | ||||
-rw-r--r-- | src/core/function/gpg/GpgKeyGetter.cpp | 84 | ||||
-rw-r--r-- | src/core/function/gpg/GpgKeyGetter.h | 37 | ||||
-rw-r--r-- | src/core/thread/CtxCheckThread.cpp | 4 |
8 files changed, 435 insertions, 137 deletions
diff --git a/src/core/GpgContext.cpp b/src/core/GpgContext.cpp index 0da963ee..733354fc 100644 --- a/src/core/GpgContext.cpp +++ b/src/core/GpgContext.cpp @@ -224,4 +224,8 @@ gpgme_error_t GpgContext::test_status_cb(void *hook, const char *keyword, return GPG_ERR_NO_ERROR; } +void GpgContext::_ctx_ref_deleter::operator()(gpgme_ctx_t _ctx) { + if (_ctx != nullptr) gpgme_release(_ctx); +} + } // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/GpgContext.h b/src/core/GpgContext.h index b148fcb5..e1f1bda4 100644 --- a/src/core/GpgContext.h +++ b/src/core/GpgContext.h @@ -116,9 +116,7 @@ class GPGFRONTEND_CORE_EXPORT GpgContext * */ struct _ctx_ref_deleter { - void operator()(gpgme_ctx_t _ctx) { - if (_ctx != nullptr) gpgme_release(_ctx); - } + void operator()(gpgme_ctx_t _ctx); }; using CtxRefHandler = diff --git a/src/core/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp index e9b8fcdc..41cf99cb 100644 --- a/src/core/GpgCoreInit.cpp +++ b/src/core/GpgCoreInit.cpp @@ -28,6 +28,9 @@ #include "GpgCoreInit.h" +#include <memory> + +#include "GpgFunctionObject.h" #include "core/GpgContext.h" #include "core/function/GlobalSettingStation.h" @@ -70,27 +73,25 @@ void init_logging() { void init_gpgfrontend_core() { // init default channel GpgFrontend::GpgContext::CreateInstance( - GPGFRONTEND_DEFAULT_CHANNEL, - [&]() -> std::unique_ptr<GpgFrontend::GpgContext> { + GPGFRONTEND_DEFAULT_CHANNEL, [&]() -> std::unique_ptr<ChannelObject> { GpgFrontend::GpgContextInitArgs args; - return std::make_unique<GpgFrontend::GpgContext>(args); + return std::unique_ptr<ChannelObject>(new GpgContext(args)); }); // init non-ascii channel GpgFrontend::GpgContext::CreateInstance( - GPGFRONTEND_NON_ASCII_CHANNEL, - [&]() -> std::unique_ptr<GpgFrontend::GpgContext> { + GPGFRONTEND_NON_ASCII_CHANNEL, [&]() -> std::unique_ptr<ChannelObject> { GpgFrontend::GpgContextInitArgs args; args.ascii = false; - return std::make_unique<GpgFrontend::GpgContext>(args); + return std::unique_ptr<ChannelObject>(new GpgContext(args)); }); } void new_default_settings_channel(int channel) { GpgFrontend::GpgContext::CreateInstance( - channel, [&]() -> std::unique_ptr<GpgFrontend::GpgContext> { + channel, [&]() -> std::unique_ptr<ChannelObject> { GpgFrontend::GpgContextInitArgs args; - return std::make_unique<GpgFrontend::GpgContext>(args); + return std::unique_ptr<ChannelObject>(new GpgContext(args)); }); } diff --git a/src/core/GpgFunctionObject.cpp b/src/core/GpgFunctionObject.cpp new file mode 100644 index 00000000..9fb55247 --- /dev/null +++ b/src/core/GpgFunctionObject.cpp @@ -0,0 +1,143 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric<[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "core/GpgFunctionObject.h" + +#include <cassert> +#include <functional> +#include <memory> +#include <mutex> +#include <shared_mutex> + +#include "easylogging++.h" + +void GpgFrontend::ChannelObject::SetChannel(int channel) { + this->channel_ = channel; +} + +int GpgFrontend::ChannelObject::GetChannel() const { return channel_; } + +int GpgFrontend::ChannelObject::GetDefaultChannel() { return _default_channel; } + +void GpgFrontend::SingletonStorage::ReleaseChannel(int channel) { + decltype(instances_map_.end()) _it; + { + std::shared_lock<std::shared_mutex> lock(instances_mutex_); + _it = instances_map_.find(channel); + } + if (_it != instances_map_.end()) instances_map_.erase(_it); + DLOG(INFO) << "channel" << channel << "released"; +} + +GpgFrontend::ChannelObject* GpgFrontend::SingletonStorage::FindObjectInChannel( + int channel) { + LOG(INFO) << "channel:" << channel << "instance address:" << &instances_map_; + // read instances_map_ + decltype(instances_map_.end()) _it; + { + std::shared_lock<std::shared_mutex> lock(instances_mutex_); + _it = instances_map_.find(channel); + if (_it == instances_map_.end()) { + LOG(INFO) << "channel:" << channel << "not found"; + return nullptr; + } else { + return _it->second.get(); + } + } +} + +std::vector<int> GpgFrontend::SingletonStorage::GetAllChannelId() { + std::vector<int> _channels; + for (const auto& [key, value] : instances_map_) { + _channels.push_back(key); + } + return _channels; +} + +GpgFrontend::ChannelObject* GpgFrontend::SingletonStorage::SetObjectInChannel( + int channel, std::unique_ptr<ChannelObject> p_obj) { + { + LOG(INFO) << "channel:" << channel + << "instance address:" << &instances_map_; + + assert(p_obj != nullptr); + if (p_obj == nullptr) return nullptr; + + auto raw_obj = p_obj.get(); + p_obj->SetChannel(channel); + { + std::unique_lock<std::shared_mutex> lock(instances_mutex_); + instances_map_.insert({channel, std::move(p_obj)}); + } + return raw_obj; + } +} + +GpgFrontend::SingletonStorage* +GpgFrontend::SingletonStorageCollection::GetSingletonStorage( + const std::type_info& type_id) { + const auto hash = type_id.hash_code(); + LOG(INFO) << "hash" << hash << "type_name:" << type_id.name(); + + while (true) { + decltype(storages_map_.end()) _it; + { + std::shared_lock<std::shared_mutex> lock(storages_mutex_); + _it = storages_map_.find(hash); + } + if (_it == storages_map_.end()) { + LOG(INFO) << "hash:" << hash << "not found"; + { + std::unique_lock<std::shared_mutex> lock(storages_mutex_); + storages_map_.insert({hash, std::make_unique<SingletonStorage>()}); + LOG(INFO) << "hash:" << hash << "created" + << "storage address:" << &storages_map_; + } + continue; + } else { + LOG(INFO) << "hash:" << hash << "found"; + return _it->second.get(); + } + } +} + +GpgFrontend::SingletonStorageCollection* +GpgFrontend::SingletonStorageCollection::GetInstance() { + static SingletonStorageCollection* instance = nullptr; + if (instance == nullptr) { + instance = new SingletonStorageCollection(); + } + return instance; +} + +GpgFrontend::ChannelObject::ChannelObject() noexcept = default; + +GpgFrontend::ChannelObject::ChannelObject(int channel) : channel_(channel) { + LOG(INFO) << "called" + << "channel:" << channel; +} diff --git a/src/core/GpgFunctionObject.h b/src/core/GpgFunctionObject.h index 391b1585..f16e4cae 100644 --- a/src/core/GpgFunctionObject.h +++ b/src/core/GpgFunctionObject.h @@ -35,20 +35,144 @@ #include <shared_mutex> #include <stdexcept> #include <string> +#include <typeinfo> +#include <utility> +#include <vector> #include "GpgConstants.h" +#include "easylogging++.h" namespace GpgFrontend { /** + * @brief object which in channel system + * + */ +class GPGFRONTEND_CORE_EXPORT ChannelObject { + public: + /** + * @brief Construct a new Default Channel Object object + * + */ + ChannelObject() noexcept; + + /** + * @brief Construct a new Channel Object object + * + * @param channel + */ + ChannelObject(int channel); + + /** + * @brief Get the Default Channel object + * + * @return int + */ + static int GetDefaultChannel(); + + /** + * @brief Get the Channel object + * + * @return int + */ + [[nodiscard]] int GetChannel() const; + + /** + * @brief Set the Channel object + * + * @param channel + */ + void SetChannel(int channel); + + private: + int channel_ = _default_channel; ///< The channel id + static constexpr int _default_channel = 0; ///< The default channel id +}; + +class GPGFRONTEND_CORE_EXPORT SingletonStorage { + public: + /** + * @brief + * + * @param channel + */ + void ReleaseChannel(int channel); + + /** + * @brief + * + * @param channel + * @return T* + */ + ChannelObject* FindObjectInChannel(int channel); + + /** + * @brief Get all the channel ids + * + * @return std::vector<int> + */ + std::vector<int> GetAllChannelId(); + + /** + * @brief Set a new object in channel object + * + * @param channel + * @param p_obj + * @return T* + */ + ChannelObject* SetObjectInChannel(int channel, + std::unique_ptr<ChannelObject> p_obj); + + private: + std::shared_mutex instances_mutex_; ///< mutex for _instances_map + std::map<int, std::unique_ptr<ChannelObject>> + instances_map_; ///< map of singleton instances +}; + +class GPGFRONTEND_CORE_EXPORT SingletonStorageCollection { + public: + /** + * @brief Get the Instance object + * + * @return SingletonStorageCollection* + */ + static SingletonStorageCollection* GetInstance(); + + /** + * @brief Get the Singleton Storage object + * + * @param singleton_function_object + * @return SingletonStorage* + */ + SingletonStorage* GetSingletonStorage(const std::type_info&); + + private: + std::shared_mutex storages_mutex_; ///< mutex for storages_map_ + std::map<size_t, std::unique_ptr<SingletonStorage>> storages_map_; +}; +/** * @brief * * @tparam T */ template <typename T> -class SingletonFunctionObject { +class SingletonFunctionObject : public ChannelObject { public: /** + * @brief prohibit copy + * + */ + SingletonFunctionObject(const SingletonFunctionObject<T>&) = delete; + + /** + * @brief prohibit copy + * + * @return SingletonFunctionObject& + */ + SingletonFunctionObject& operator=(const SingletonFunctionObject<T>&) = + delete; + + /** * @brief Get the Instance object * * @param channel @@ -59,10 +183,19 @@ class SingletonFunctionObject { static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value, "T not derived from SingletonFunctionObject<T>"); - auto _p_pbj = find_object_in_channel(channel); - if (_p_pbj == nullptr) - return *set_object_in_channel(channel, std::make_unique<T>(channel)); - else + auto p_storage = + SingletonStorageCollection::GetInstance()->GetSingletonStorage( + typeid(T)); + + auto* _p_pbj = (T*)(p_storage->FindObjectInChannel(channel)); + + LOG(INFO) << "object address" << _p_pbj; + + if (_p_pbj == nullptr) { + auto new_obj = std::unique_ptr<ChannelObject>(new T(channel)); + LOG(INFO) << "create new object"; + return *(T*)(p_storage->SetObjectInChannel(channel, std::move(new_obj))); + } else return *_p_pbj; } @@ -73,33 +206,22 @@ class SingletonFunctionObject { * @param factory * @return T& */ - static T& CreateInstance(int channel, - std::function<std::unique_ptr<T>(void)> factory) { + static T& CreateInstance( + int channel, + std::function<std::unique_ptr<ChannelObject>(void)> factory) { static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value, "T not derived from SingletonFunctionObject<T>"); - auto _p_pbj = find_object_in_channel(channel); - if (_p_pbj == nullptr) - return *set_object_in_channel(channel, std::move(factory())); - else - return *_p_pbj; - } + auto p_storage = + SingletonStorageCollection::GetInstance()->GetSingletonStorage( + typeid(T)); - /** - * @brief Create a Instance object - * - * @param channel - * @param p_obj - * @return T& - */ - static T& CreateInstance(int channel, std::unique_ptr<T> p_obj = nullptr) { - static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value, - "T not derived from SingletonFunctionObject<T>"); + auto _p_pbj = (T*)(p_storage->FindObjectInChannel(channel)); - auto _p_pbj = find_object_in_channel(channel); - if (_p_pbj == nullptr) - return *set_object_in_channel(channel, std::move(p_obj)); - else + if (_p_pbj == nullptr) { + return *( + T*)(p_storage->SetObjectInChannel(channel, std::move(factory()))); + } else return *_p_pbj; } @@ -109,14 +231,10 @@ class SingletonFunctionObject { * @param channel * @return T& */ - static T& ReleaseChannel(int channel) { - decltype(_instances_map.end()) _it; - { - std::shared_lock lock(_instances_mutex); - _it = _instances_map.find(channel); - } - if (_it != _instances_map.end()) _instances_map.erase(_it); - DLOG(INFO) << "channel" << channel << "released"; + static void ReleaseChannel(int channel) { + SingletonStorageCollection::GetInstance() + ->GetSingletonStorage(typeid(T)) + ->ReleaseChannel(channel); } /** @@ -124,14 +242,25 @@ class SingletonFunctionObject { * * @return int */ - static int GetDefaultChannel() { return _default_channel; } + static int GetDefaultChannel() { return ChannelObject::GetDefaultChannel(); } /** * @brief Get the Channel object * * @return int */ - [[nodiscard]] int GetChannel() const { return channel_; } + [[nodiscard]] int GetChannel() const { return ChannelObject::GetChannel(); } + + /** + * @brief Get all the channel ids + * + * @return std::vector<int> + */ + static std::vector<int> GetAllChannelId() { + return SingletonStorageCollection::GetInstance() + ->GetSingletonStorage(typeid(T)) + ->GetAllChannelId(); + } /** * @brief Construct a new Singleton Function Object object @@ -163,85 +292,17 @@ class SingletonFunctionObject { * * @param channel */ - explicit SingletonFunctionObject(int channel) : channel_(channel) {} + explicit SingletonFunctionObject(int channel) : ChannelObject(channel) { + LOG(INFO) << "called" + << "channel:" << channel; + } /** * @brief Destroy the Singleton Function Object object * */ virtual ~SingletonFunctionObject() = default; - - /** - * @brief Set the Channel object - * - * @param channel - */ - void SetChannel(int channel) { this->channel_ = channel; } - - private: - int channel_ = _default_channel; ///< - static int _default_channel; ///< - static std::mutex _instance_mutex; ///< - static std::shared_mutex _instances_mutex; ///< - static std::unique_ptr<T> _instance; ///< - static std::map<int, std::unique_ptr<T>> _instances_map; ///< - - /** - * @brief - * - * @param channel - * @return T* - */ - static T* find_object_in_channel(int channel) { - // read _instances_map - decltype(_instances_map.end()) _it; - { - std::shared_lock lock(_instances_mutex); - _it = _instances_map.find(channel); - if (_it == _instances_map.end()) - return nullptr; - else - return _it->second.get(); - } - } - - /** - * @brief Set the object in channel object - * - * @param channel - * @param p_obj - * @return T* - */ - static T* set_object_in_channel(int channel, std::unique_ptr<T> p_obj) { - { - if (p_obj == nullptr) p_obj = std::make_unique<T>(); - T* obj = p_obj.get(); - obj->SetChannel(channel); - { - std::unique_lock lock(_instances_mutex); - _instances_map.insert({channel, std::move(p_obj)}); - } - return obj; - } - } }; - -template <typename T> -int SingletonFunctionObject<T>::_default_channel = - GpgFrontend::GPGFRONTEND_DEFAULT_CHANNEL; - -template <typename T> -std::mutex SingletonFunctionObject<T>::_instance_mutex; - -template <typename T> -std::shared_mutex SingletonFunctionObject<T>::_instances_mutex; - -template <typename T> -std::unique_ptr<T> SingletonFunctionObject<T>::_instance = nullptr; - -template <typename T> -std::map<int, std::unique_ptr<T>> SingletonFunctionObject<T>::_instances_map; - } // namespace GpgFrontend #endif // GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H diff --git a/src/core/function/gpg/GpgKeyGetter.cpp b/src/core/function/gpg/GpgKeyGetter.cpp index cbd40efc..9a7b505c 100644 --- a/src/core/function/gpg/GpgKeyGetter.cpp +++ b/src/core/function/gpg/GpgKeyGetter.cpp @@ -30,12 +30,32 @@ #include <gpg-error.h> +#include <mutex> +#include <shared_mutex> +#include <utility> + #include "GpgConstants.h" +#include "easylogging++.h" +#include "model/GpgKey.h" GpgFrontend::GpgKeyGetter::GpgKeyGetter(int channel) - : SingletonFunctionObject<GpgKeyGetter>(channel) {} + : SingletonFunctionObject<GpgKeyGetter>(channel) { + LOG(INFO) << "called" + << "channel:" << channel; +} GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetKey(const std::string& fpr) { + LOG(INFO) << "called"; + + // find in cache first + { + std::lock_guard<std::mutex> lock(keys_cache_mutex_); + if (keys_cache_.find(fpr) != keys_cache_.end()) { + std::lock_guard<std::mutex> lock(ctx_mutex_); + return keys_cache_[fpr].Copy(); + } + } + gpgme_key_t _p_key = nullptr; gpgme_get_key(ctx_, fpr.c_str(), &_p_key, 1); if (_p_key == nullptr) { @@ -48,6 +68,15 @@ GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetKey(const std::string& fpr) { GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetPubkey( const std::string& fpr) { + // find in cache first + { + std::lock_guard<std::mutex> lock(keys_cache_mutex_); + if (keys_cache_.find(fpr) != keys_cache_.end()) { + std::lock_guard<std::mutex> lock(ctx_mutex_); + return keys_cache_[fpr].Copy(); + } + } + gpgme_key_t _p_key = nullptr; gpgme_get_key(ctx_, fpr.c_str(), &_p_key, 0); if (_p_key == nullptr) @@ -56,28 +85,59 @@ GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetPubkey( } GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::FetchKey() { - gpgme_error_t err; + // get the lock + std::lock_guard<std::mutex> lock(keys_cache_mutex_); + + LOG(INFO) << "GpgKeyGetter FetchKey" + << "channel id:" << GetChannel(); auto keys_list = std::make_unique<GpgKeyLinkList>(); - LOG(INFO) << "GpgKeyGetter FetchKey" - << "ctx address" << ctx_; + LOG(INFO) << "cache address:" << &keys_cache_ << "object address" << this; - err = gpgme_op_keylist_start(ctx_, nullptr, 0); + for (const auto& [key, value] : keys_cache_) { + LOG(INFO) << "FetchKey Id:" << value.GetId(); + keys_list->push_back(value.Copy()); + } + LOG(INFO) << "ended"; + return keys_list; +} + +void GpgFrontend::GpgKeyGetter::FlushKeyCache() { + LOG(INFO) << "called" + << "channel id: " << GetChannel(); + + // clear the keys cache + keys_cache_.clear(); + + // init + GpgError err = gpgme_op_keylist_start(ctx_, nullptr, 0); + + // for debug assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR); - gpgme_key_t key; - while ((err = gpgme_op_keylist_next(ctx_, &key)) == GPG_ERR_NO_ERROR) { - keys_list->push_back(GetKey(key->fpr)); + // return when error + if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) return; + + { + // get the lock + std::lock_guard<std::mutex> lock(keys_cache_mutex_); + gpgme_key_t key; + while ((err = gpgme_op_keylist_next(ctx_, &key)) == GPG_ERR_NO_ERROR) { + LOG(INFO) << "LoadKey Fpr:" << key->fpr << "Id:" << key->subkeys->keyid; + keys_cache_.insert({key->subkeys->keyid, GpgKey(std::move(key))}); + } } + LOG(INFO) << "cache address:" << &keys_cache_ << "object address" << this; + + // for debug assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_EOF); err = gpgme_op_keylist_end(ctx_); - assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_NO_ERROR); - return keys_list; + LOG(INFO) << "ended"; } GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeys( @@ -89,6 +149,8 @@ GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeys( GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::GetKeysCopy( const GpgFrontend::KeyLinkListPtr& keys) { + // get the lock + std::lock_guard<std::mutex> lock(ctx_mutex_); auto keys_copy = std::make_unique<GpgKeyLinkList>(); for (const auto& key : *keys) keys_copy->push_back(key.Copy()); return keys_copy; @@ -96,6 +158,8 @@ GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::GetKeysCopy( GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeysCopy( const GpgFrontend::KeyListPtr& keys) { + // get the lock + std::lock_guard<std::mutex> lock(ctx_mutex_); auto keys_copy = std::make_unique<KeyArgsList>(); for (const auto& key : *keys) keys_copy->push_back(key.Copy()); return keys_copy; diff --git a/src/core/function/gpg/GpgKeyGetter.h b/src/core/function/gpg/GpgKeyGetter.h index d63238f5..72cd777c 100644 --- a/src/core/function/gpg/GpgKeyGetter.h +++ b/src/core/function/gpg/GpgKeyGetter.h @@ -29,6 +29,9 @@ #ifndef GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H #define GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H +#include <mutex> +#include <vector> + #include "core/GpgContext.h" #include "core/GpgFunctionObject.h" #include "core/GpgModel.h" @@ -56,7 +59,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter * @param fpr * @return GpgKey */ - GpgKey GetKey(const std::string& fpr); + GpgKey GetKey(const std::string& id); /** * @brief Get the Keys object @@ -72,22 +75,28 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter * @param fpr * @return GpgKey */ - GpgKey GetPubkey(const std::string& fpr); + GpgKey GetPubkey(const std::string& id); /** - * @brief + * @brief Get all the keys by receiving a linked list * * @return KeyLinkListPtr */ KeyLinkListPtr FetchKey(); /** + * @brief flush the keys in the cache + * + */ + void FlushKeyCache(); + + /** * @brief Get the Keys Copy object * * @param keys * @return KeyListPtr */ - static KeyListPtr GetKeysCopy(const KeyListPtr& keys); + KeyListPtr GetKeysCopy(const KeyListPtr& keys); /** * @brief Get the Keys Copy object @@ -95,7 +104,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter * @param keys * @return KeyLinkListPtr */ - static KeyLinkListPtr GetKeysCopy(const KeyLinkListPtr& keys); + KeyLinkListPtr GetKeysCopy(const KeyLinkListPtr& keys); private: /** @@ -104,6 +113,24 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter */ GpgContext& ctx_ = GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); + + /** + * @brief shared mutex for the keys cache + * + */ + mutable std::mutex ctx_mutex_; + + /** + * @brief cache the keys with key fpr + * + */ + std::map<std::string, GpgKey> keys_cache_; + + /** + * @brief shared mutex for the keys cache + * + */ + mutable std::mutex keys_cache_mutex_; }; } // namespace GpgFrontend diff --git a/src/core/thread/CtxCheckThread.cpp b/src/core/thread/CtxCheckThread.cpp index 77571dfd..edec8855 100644 --- a/src/core/thread/CtxCheckThread.cpp +++ b/src/core/thread/CtxCheckThread.cpp @@ -48,7 +48,7 @@ void GpgFrontend::CtxCheckThread::run() { if (!GpgContext::GetInstance().good()) { emit SignalGnupgNotInstall(); } - // Try fetching key + // Try flushing key cache else - GpgFrontend::GpgKeyGetter::GetInstance().FetchKey(); + GpgFrontend::GpgKeyGetter::GetInstance().FlushKeyCache(); } |