diff options
Diffstat (limited to 'src/core/module')
-rw-r--r-- | src/core/module/Event.cpp | 9 | ||||
-rw-r--r-- | src/core/module/GlobalModuleContext.cpp | 48 | ||||
-rw-r--r-- | src/core/module/GlobalModuleContext.h | 2 | ||||
-rw-r--r-- | src/core/module/Module.cpp | 11 | ||||
-rw-r--r-- | src/core/module/ModuleInit.cpp | 60 | ||||
-rw-r--r-- | src/core/module/ModuleManager.cpp | 166 | ||||
-rw-r--r-- | src/core/module/ModuleManager.h | 14 |
7 files changed, 211 insertions, 99 deletions
diff --git a/src/core/module/Event.cpp b/src/core/module/Event.cpp index 873e728d..56f45261 100644 --- a/src/core/module/Event.cpp +++ b/src/core/module/Event.cpp @@ -38,7 +38,7 @@ class Event::Impl { : event_identifier_(std::move(event_id)), callback_(std::move(callback)), callback_thread_(QThread::currentThread()) { - data_.insert(params); + if (!params.empty()) data_.insert(params); } auto operator[](const QString& key) const -> std::optional<ParameterValue> { @@ -98,17 +98,16 @@ class Event::Impl { event->id = GFStrDup(event_identifier_); event->trigger_id = GFStrDup(trigger_uuid_); + event->params = nullptr; GFModuleEventParam* l_param = nullptr; GFModuleEventParam* p_param; - int index = 0; - #if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0) for (const auto& data : data_.asKeyValueRange()) { p_param = static_cast<GFModuleEventParam*>( SecureMalloc(sizeof(GFModuleEventParam))); - if (index++ == 0) event->params = p_param; + if (event->params == nullptr) event->params = p_param; p_param->name = GFStrDup(data.first); p_param->value = GFStrDup(data.second); @@ -121,7 +120,7 @@ class Event::Impl { for (auto it = data_.keyValueBegin(); it != data_.keyValueEnd(); ++it) { p_param = static_cast<GFModuleEventParam*>( SecureMalloc(sizeof(GFModuleEventParam))); - if (index++ == 0) event->params = p_param; + if (event->params == nullptr) event->params = p_param; p_param->name = GFStrDup(it->first); p_param->value = GFStrDup(it->second); diff --git a/src/core/module/GlobalModuleContext.cpp b/src/core/module/GlobalModuleContext.cpp index 08090d33..25ddce65 100644 --- a/src/core/module/GlobalModuleContext.cpp +++ b/src/core/module/GlobalModuleContext.cpp @@ -102,14 +102,12 @@ class GlobalModuleContext::Impl { module_register_table_.find(module->GetModuleIdentifier()) != module_register_table_.end()) { FLOG_W("module is null or have already registered this module"); + registered_modules_++; return false; } - if (module->Register() != 0) { - LOG_W() << "register module " << module->GetModuleIdentifier() - << " failed"; - return false; - } + LOG_D() << "(+) module: " << module->GetModuleIdentifier() + << "registering..."; auto register_info = GpgFrontend::SecureCreateSharedObject<ModuleRegisterInfo>(); @@ -124,13 +122,28 @@ class GlobalModuleContext::Impl { .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Module) ->GetThread()); - // Register the module with its identifier. + // register the module with its identifier. module_register_table_[module->GetModuleIdentifier()] = register_info; + if (module->Register() != 0) { + LOG_W() << "module: " << module->GetModuleIdentifier() + << " register failed."; + register_info->registered = false; + registered_modules_++; + return false; + } + + register_info->registered = true; + registered_modules_++; + + LOG_D() << "(+) module: " << module->GetModuleIdentifier() << "registered."; + return true; } auto ActiveModule(ModuleIdentifier module_id) -> bool { + LOG_D() << "(*) module: " << module_id << "activating..."; + // Search for the module in the register table. auto module_info_opt = search_module_register_table(module_id); if (!module_info_opt.has_value()) { @@ -140,6 +153,12 @@ class GlobalModuleContext::Impl { auto module_info = module_info_opt.value(); + if (!module_info->registered) { + LOG_W() << "module id:" << module_id + << " is not properly register, activation abort..."; + return false; + } + // try to get module from module info auto module = module_info->module; if (module == nullptr) { @@ -152,6 +171,8 @@ class GlobalModuleContext::Impl { if (!module_info->activate) { module->Active(); module_info->activate = true; + + LOG_D() << "(*) module: " << module_id << "activated."; } return module_info->activate; @@ -293,6 +314,12 @@ class GlobalModuleContext::Impl { return m.has_value() && m->get()->activate; } + [[nodiscard]] auto IsModuleRegistered(const ModuleIdentifier& m_id) const + -> bool { + auto m = search_module_register_table(m_id); + return m.has_value() && m->get()->activate; + } + auto IsIntegratedModule(ModuleIdentifier m_id) -> bool { auto m = search_module_register_table(m_id); return m.has_value() && m->get()->integrated; @@ -314,10 +341,13 @@ class GlobalModuleContext::Impl { return module_info->get()->listening_event_ids; } + auto GetRegisteredModuleNum() const -> int { return registered_modules_; } + private: struct ModuleRegisterInfo { int channel; ModulePtr module; + bool registered; bool activate; bool integrated; QList<QString> listening_event_ids; @@ -334,6 +364,7 @@ class GlobalModuleContext::Impl { std::set<int> acquired_channel_; TaskRunnerPtr default_task_runner_; + int registered_modules_ = 0; auto acquire_new_unique_channel() -> int { int random_channel = QRandomGenerator::global()->bounded(65535); @@ -440,4 +471,9 @@ auto GlobalModuleContext::GetModuleListening(ModuleIdentifier module_id) -> QList<EventIdentifier> { return p_->GetModuleListening(module_id); } + +auto GlobalModuleContext::GetRegisteredModuleNum() const -> int { + return p_->GetRegisteredModuleNum(); +} + } // namespace GpgFrontend::Module diff --git a/src/core/module/GlobalModuleContext.h b/src/core/module/GlobalModuleContext.h index e3dabe0e..f122f36f 100644 --- a/src/core/module/GlobalModuleContext.h +++ b/src/core/module/GlobalModuleContext.h @@ -90,6 +90,8 @@ class GPGFRONTEND_CORE_EXPORT GlobalModuleContext : public QObject { auto ListAllRegisteredModuleID() -> QList<ModuleIdentifier>; + [[nodiscard]] auto GetRegisteredModuleNum() const -> int; + private: class Impl; SecureUniquePtr<Impl> p_; diff --git a/src/core/module/Module.cpp b/src/core/module/Module.cpp index becda4b6..1be4a4bd 100644 --- a/src/core/module/Module.cpp +++ b/src/core/module/Module.cpp @@ -110,10 +110,10 @@ class Module::Impl { if (qt_env_ver_major != QString::number(QT_VERSION_MAJOR) + "." || qt_env_ver_minor != QString::number(QT_VERSION_MINOR) + ".") { - LOG_W() << "uncompatible module: " << identifier_ - << ", reason sdk version: " << qt_env_ver_ - << "current sdk version: " << QString::fromUtf8(QT_VERSION_STR) - << ", abort..."; + LOG_W() << "module: " << identifier_ + << "is not compatible, reason module qt version: " << qt_env_ver_ + << ", but application qt version: " + << QString::fromUtf8(QT_VERSION_STR) << ", abort..."; return; } @@ -274,7 +274,8 @@ auto Module::Register() -> int { return p_->Register(); } auto Module::Active() -> int { return p_->Active(); } auto Module::Exec(EventReference event) -> int { - return p_->Exec(std::move(event)); + LOG_D() << "module" << GetModuleIdentifier() << "executing..."; + return p_->Exec(event); } auto Module::Deactivate() -> int { return p_->Deactivate(); } diff --git a/src/core/module/ModuleInit.cpp b/src/core/module/ModuleInit.cpp index 3c71a45b..972e7025 100644 --- a/src/core/module/ModuleInit.cpp +++ b/src/core/module/ModuleInit.cpp @@ -38,15 +38,17 @@ namespace GpgFrontend::Module { -void LoadModuleFromPath(const QString& mods_path, bool integrated) { +auto SearchModuleFromPath(const QString& mods_path, + bool integrated) -> QMap<QString, bool> { + QMap<QString, bool> m; for (const auto& module_library_name : QDir(mods_path).entryList( QStringList() << "*.so" << "*.dll" << "*.dylib", QDir::Files)) { - ModuleManager::GetInstance().LoadModule( - mods_path + "/" + module_library_name, integrated); + m[mods_path + "/" + module_library_name] = integrated; } + return m; } -auto LoadIntegratedMods() -> bool { +auto LoadIntegratedMods() -> QMap<QString, bool> { const auto exec_binary_path = QCoreApplication::applicationDirPath(); QString mods_path = exec_binary_path + "/modules"; @@ -71,37 +73,63 @@ auto LoadIntegratedMods() -> bool { if (!QDir(mods_path).exists()) { LOG_W() << "integrated module directory at path: " << mods_path << " not found, abort..."; - return false; + return {}; } - LoadModuleFromPath(mods_path, true); - - return true; + return SearchModuleFromPath(mods_path, true); } -auto LoadExternalMods() -> bool { +auto LoadExternalMods() -> QMap<QString, bool> { auto mods_path = GpgFrontend::GlobalSettingStation::GetInstance().GetModulesDir(); if (!QDir(mods_path).exists()) { LOG_W() << "external module directory at path " << mods_path << " not found, abort..."; - return false; + return {}; } - LoadModuleFromPath(mods_path, false); - - return true; + return SearchModuleFromPath(mods_path, false); } void LoadGpgFrontendModules(ModuleInitArgs) { + // give user ability to give up all modules + auto disable_loading_all_modules = + GlobalSettingStation::GetInstance() + .GetSettings() + .value("basic/disable_loading_all_modules", false) + .toBool(); + if (disable_loading_all_modules) return; + // must init at default thread before core - Thread::TaskRunnerGetter::GetInstance().GetTaskRunner()->PostTask( - new Thread::Task( + Thread::TaskRunnerGetter::GetInstance() + .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Module) + ->PostTask(new Thread::Task( [](const DataObjectPtr&) -> int { - return LoadIntegratedMods() && LoadExternalMods() ? 0 : -1; + QMap<QString, bool> modules = LoadIntegratedMods(); + modules.insert(LoadExternalMods()); + + auto& manager = ModuleManager::GetInstance(); + manager.SetNeedRegisterModulesNum(static_cast<int>(modules.size())); + +#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0) + for (const auto& m : modules.asKeyValueRange()) { + manager.LoadModule(m.first, m.second); + } +#else + for (auto it = modules.keyValueBegin(); it != modules.keyValueEnd(); + ++it) { + manager.LoadModule(it->first, it->second); + } +#endif + + LOG_D() << "all modules are loaded into memory."; + return 0; }, "modules_system_init_task")); + + LOG_D() << "dear module manager, is all module registered? answer: " + << ModuleManager::GetInstance().IsAllModulesRegistered(); } void ShutdownGpgFrontendModules() {} diff --git a/src/core/module/ModuleManager.cpp b/src/core/module/ModuleManager.cpp index 5f8895be..8f97adc3 100644 --- a/src/core/module/ModuleManager.cpp +++ b/src/core/module/ModuleManager.cpp @@ -54,66 +54,79 @@ class ModuleManager::Impl { ~Impl() = default; auto LoadAndRegisterModule(const QString& module_library_path, - bool integrated_module) -> void { - // give user ability to give up all modules - auto disable_loading_all_modules = - GlobalSettingStation::GetInstance() - .GetSettings() - .value("basic/disable_loading_all_modules", false) - .toBool(); - if (disable_loading_all_modules) return; - - Thread::TaskRunnerGetter::GetInstance() - .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default) - ->PostTask(new Thread::Task( - [=](GpgFrontend::DataObjectPtr) -> int { - QLibrary module_library(module_library_path); - if (!module_library.load()) { - LOG_W() << "module manager failed to load module: " - << module_library.fileName() - << ", reason: " << module_library.errorString(); - return -1; - } - - auto module = SecureCreateSharedObject<Module>(module_library); - if (!module->IsGood()) { - LOG_W() << "module manager failed to load module, " - "reason: illegal module: " - << module_library.fileName(); - return -1; - } - - module->SetGPC(gmc_.get()); - if (!gmc_->RegisterModule(module, integrated_module)) return -1; - - const auto module_id = module->GetModuleIdentifier(); - const auto module_hash = module->GetModuleHash(); - - SettingsObject so(QString("module.%1.so").arg(module_id)); - ModuleSO module_so(so); - - // reset module settings if necessary - if (module_so.module_id != module_id || - module_so.module_hash != module_hash) { - module_so.module_id = module_id; - module_so.module_hash = module_hash; - // auto active integrated module by default - module_so.auto_activate = integrated_module; - module_so.set_by_user = false; - - so.Store(module_so.ToJson()); - } - - // if this module need auto active - if (module_so.auto_activate) { - if (!gmc_->ActiveModule(module_id)) { - return -1; - } - } + bool integrated_module) -> bool { + QLibrary module_library(module_library_path); + if (!module_library.load()) { + LOG_W() << "module manager failed to load module: " + << module_library.fileName() + << ", reason: " << module_library.errorString(); + need_register_modules_--; + return false; + } + + auto module = SecureCreateSharedObject<Module>(module_library); + if (!module->IsGood()) { + LOG_W() << "module manager failed to load module, " + "reason: illegal module: " + << module_library.fileName(); + need_register_modules_--; + return false; + } + + module->SetGPC(gmc_.get()); + + LOG_D() << "a new need register module: " + << QFileInfo(module_library_path).fileName(); + + auto runner = Thread::TaskRunnerGetter::GetInstance().GetTaskRunner( + Thread::TaskRunnerGetter::kTaskRunnerType_Module); + + runner->PostTask(new Thread::Task( + [=](GpgFrontend::DataObjectPtr) -> int { + // register module + if (!gmc_->RegisterModule(module, integrated_module)) return -1; + + return 0; + }, + __func__, nullptr)); + + runner->PostTask(new Thread::Task( + [=](GpgFrontend::DataObjectPtr) -> int { + const auto module_id = module->GetModuleIdentifier(); + const auto module_hash = module->GetModuleHash(); + + SettingsObject so(QString("module.%1.so").arg(module_id)); + ModuleSO module_so(so); + + // reset module settings if necessary + if (module_so.module_id != module_id || + module_so.module_hash != module_hash) { + module_so.module_id = module_id; + module_so.module_hash = module_hash; + // auto active integrated module by default + module_so.auto_activate = integrated_module; + module_so.set_by_user = false; + + so.Store(module_so.ToJson()); + } + + // if this module need auto active + if (module_so.auto_activate) { + if (!gmc_->ActiveModule(module_id)) { + return -1; + } + } + + return 0; + }, + __func__, nullptr)); + + return true; + } - return 0; - }, - __func__, nullptr)); + void SetNeedRegisterModulesNum(int n) { + if (need_register_modules_ != -1 || n < 0) return; + need_register_modules_ = n; } auto SearchModule(ModuleIdentifier module_id) -> ModulePtr { @@ -126,7 +139,7 @@ class ModuleManager::Impl { void RegisterModule(const ModulePtr& module) { Thread::TaskRunnerGetter::GetInstance() - .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default) + .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Module) ->PostTask(new Thread::Task( [=](GpgFrontend::DataObjectPtr) -> int { module->SetGPC(gmc_.get()); @@ -138,7 +151,7 @@ class ModuleManager::Impl { void ListenEvent(const ModuleIdentifier& module_id, const EventIdentifier& event_id) { Thread::TaskRunnerGetter::GetInstance() - .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default) + .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Module) ->PostTask(new Thread::Task( [=](const GpgFrontend::DataObjectPtr&) -> int { gmc_->ListenEvent(module_id, event_id); @@ -149,7 +162,7 @@ class ModuleManager::Impl { void TriggerEvent(const EventReference& event) { Thread::TaskRunnerGetter::GetInstance() - .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default) + .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Module) ->PostTask(new Thread::Task( [=](const GpgFrontend::DataObjectPtr&) -> int { gmc_->TriggerEvent(event); @@ -170,7 +183,7 @@ class ModuleManager::Impl { void ActiveModule(const ModuleIdentifier& identifier) { Thread::TaskRunnerGetter::GetInstance() - .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default) + .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Module) ->PostTask(new Thread::Task( [=](const GpgFrontend::DataObjectPtr&) -> int { gmc_->ActiveModule(identifier); @@ -181,7 +194,7 @@ class ModuleManager::Impl { void DeactivateModule(const ModuleIdentifier& identifier) { Thread::TaskRunnerGetter::GetInstance() - .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default) + .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Module) ->PostTask(new Thread::Task( [=](const GpgFrontend::DataObjectPtr&) -> int { gmc_->DeactivateModule(identifier); @@ -219,6 +232,14 @@ class ModuleManager::Impl { return gmc_->IsIntegratedModule(id); } + auto IsAllModulesRegistered() { + if (need_register_modules_ == -1) return false; + LOG_D() << "module manager report, need register: " + << need_register_modules_ << "registered" + << gmc_->GetRegisteredModuleNum(); + return need_register_modules_ == gmc_->GetRegisteredModuleNum(); + } + auto GRT() -> GlobalRegisterTable* { return grt_.get(); } private: @@ -226,12 +247,18 @@ class ModuleManager::Impl { SecureUniquePtr<GlobalModuleContext> gmc_; SecureUniquePtr<GlobalRegisterTable> grt_; QList<QLibrary> module_libraries_; + int need_register_modules_ = -1; }; auto IsModuleActivate(ModuleIdentifier id) -> bool { return ModuleManager::GetInstance().IsModuleActivated(id); } +auto GPGFRONTEND_CORE_EXPORT IsModuleExists(ModuleIdentifier id) -> bool { + auto module = ModuleManager::GetInstance().SearchModule(id); + return module != nullptr && module->IsGood(); +} + auto UpsertRTValue(const QString& namespace_, const QString& key, const std::any& value) -> bool { return ModuleManager::GetInstance().UpsertRTValue(namespace_, key, @@ -254,8 +281,8 @@ ModuleManager::ModuleManager(int channel) ModuleManager::~ModuleManager() = default; -void ModuleManager::LoadModule(QString module_library_path, - bool integrated_module) { +auto ModuleManager::LoadModule(QString module_library_path, + bool integrated_module) -> bool { return p_->LoadAndRegisterModule(module_library_path, integrated_module); } @@ -332,4 +359,11 @@ auto ModuleManager::ListAllRegisteredModuleID() -> QList<ModuleIdentifier> { auto ModuleManager::GRT() -> GlobalRegisterTable* { return p_->GRT(); } +auto ModuleManager::IsAllModulesRegistered() -> bool { + return p_->IsAllModulesRegistered(); +} + +void ModuleManager::SetNeedRegisterModulesNum(int n) { + p_->SetNeedRegisterModulesNum(n); +} } // namespace GpgFrontend::Module
\ No newline at end of file diff --git a/src/core/module/ModuleManager.h b/src/core/module/ModuleManager.h index 365dd8fd..5c703bf3 100644 --- a/src/core/module/ModuleManager.h +++ b/src/core/module/ModuleManager.h @@ -65,14 +65,18 @@ class GPGFRONTEND_CORE_EXPORT ModuleManager virtual ~ModuleManager() override; - auto LoadModule(QString, bool) -> void; + auto LoadModule(QString, bool) -> bool; auto SearchModule(ModuleIdentifier) -> ModulePtr; + void SetNeedRegisterModulesNum(int); + auto ListAllRegisteredModuleID() -> QList<ModuleIdentifier>; void RegisterModule(ModulePtr); + auto IsAllModulesRegistered() -> bool; + auto IsModuleActivated(ModuleIdentifier) -> bool; auto IsIntegratedModule(ModuleIdentifier) -> bool; @@ -139,6 +143,14 @@ auto GPGFRONTEND_CORE_EXPORT IsModuleActivate(ModuleIdentifier) -> bool; /** * @brief * + * @return true + * @return false + */ +auto GPGFRONTEND_CORE_EXPORT IsModuleExists(ModuleIdentifier) -> bool; + +/** + * @brief + * * @param namespace_ * @param key * @param value |