aboutsummaryrefslogtreecommitdiffstats
path: root/src/core/module
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/module')
-rw-r--r--src/core/module/Event.cpp9
-rw-r--r--src/core/module/GlobalModuleContext.cpp48
-rw-r--r--src/core/module/GlobalModuleContext.h2
-rw-r--r--src/core/module/Module.cpp11
-rw-r--r--src/core/module/ModuleInit.cpp60
-rw-r--r--src/core/module/ModuleManager.cpp166
-rw-r--r--src/core/module/ModuleManager.h14
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