From 7be0fcf4fd3e47fc3d50401753fd4086c146feeb Mon Sep 17 00:00:00 2001 From: Wiebe Cazemier Date: Sun, 7 Mar 2021 15:56:40 +0100 Subject: [PATCH] Quit threads by using task queue --- authplugin.cpp | 11 +++++++++++ authplugin.h | 3 +++ mainapp.cpp | 7 ++++++- threaddata.cpp | 18 +++++++++++++++++- threaddata.h | 5 ++++- 5 files changed, 41 insertions(+), 3 deletions(-) diff --git a/authplugin.cpp b/authplugin.cpp index 8ef2767..60e8e86 100644 --- a/authplugin.cpp +++ b/authplugin.cpp @@ -97,6 +97,9 @@ void AuthPlugin::init() if (settings.authPluginSerializeInit) lock.lock(); + if (quitting) + return; + AuthOptCompatWrap &authOpts = settings.getAuthOptsCompat(); int result = init_v2(&pluginData, authOpts.head(), authOpts.size()); if (result != 0) @@ -125,6 +128,9 @@ void AuthPlugin::securityInit(bool reloading) if (settings.authPluginSerializeInit) lock.lock(); + if (quitting) + return; + AuthOptCompatWrap &authOpts = settings.getAuthOptsCompat(); int result = security_init_v2(pluginData, authOpts.head(), authOpts.size(), reloading); if (result != 0) @@ -201,6 +207,11 @@ AuthResult AuthPlugin::unPwdCheck(const std::string &username, const std::string return r; } +void AuthPlugin::setQuitting() +{ + this->quitting = true; +} + std::string AuthResultToString(AuthResult r) { { diff --git a/authplugin.h b/authplugin.h index ec4039a..c90fc5f 100644 --- a/authplugin.h +++ b/authplugin.h @@ -63,6 +63,7 @@ class AuthPlugin Logger *logger = nullptr; bool initialized = false; bool wanted = false; + bool quitting = false; void *loadSymbol(void *handle, const char *symbol) const; public: @@ -79,6 +80,8 @@ public: AuthResult aclCheck(const std::string &clientid, const std::string &username, const std::string &topic, AclAccess access); AuthResult unPwdCheck(const std::string &username, const std::string &password); + void setQuitting(); + }; #endif // AUTHPLUGIN_H diff --git a/mainapp.cpp b/mainapp.cpp index 3bf3bfa..5161096 100644 --- a/mainapp.cpp +++ b/mainapp.cpp @@ -440,7 +440,12 @@ void MainApp::start() for(std::shared_ptr &thread : threads) { - thread->quit(); + thread->queueQuit(); + } + + for(std::shared_ptr &thread : threads) + { + thread->waitForQuit(); } for(auto pair : listenerMap) diff --git a/threaddata.cpp b/threaddata.cpp index bcfbcd0..e273caa 100644 --- a/threaddata.cpp +++ b/threaddata.cpp @@ -52,7 +52,6 @@ void ThreadData::start(thread_f f) void ThreadData::quit() { running = false; - thread.join(); } void ThreadData::giveClient(Client_p client) @@ -109,6 +108,23 @@ void ThreadData::queueDoKeepAliveCheck() wakeUpThread(); } +void ThreadData::queueQuit() +{ + std::lock_guard locker(taskQueueMutex); + + auto f = std::bind(&ThreadData::quit, this); + taskQueue.push_front(f); + + authPlugin.setQuitting(); + + wakeUpThread(); +} + +void ThreadData::waitForQuit() +{ + thread.join(); +} + // TODO: profile how fast hash iteration is. Perhaps having a second list/vector is beneficial? void ThreadData::doKeepAliveCheck() { diff --git a/threaddata.h b/threaddata.h index 2dc3321..aecd8bd 100644 --- a/threaddata.h +++ b/threaddata.h @@ -33,6 +33,7 @@ class ThreadData void reload(std::shared_ptr settings); void wakeUpThread(); void doKeepAliveCheck(); + void quit(); public: Settings settingsLocalCopy; // Is updated on reload, within the thread loop. @@ -50,7 +51,7 @@ public: ThreadData(ThreadData &&other) = delete; void start(thread_f f); - void quit(); + void giveClient(Client_p client); Client_p getClient(int fd); void removeClient(Client_p client); @@ -60,6 +61,8 @@ public: void initAuthPlugin(); void queueReload(std::shared_ptr settings); void queueDoKeepAliveCheck(); + void queueQuit(); + void waitForQuit(); }; -- libgit2 0.21.4