Commit 7be0fcf4fd3e47fc3d50401753fd4086c146feeb

Authored by Wiebe Cazemier
1 parent b724f979

Quit threads by using task queue

This fixes the 100ms wait time requirement.
authplugin.cpp
... ... @@ -97,6 +97,9 @@ void AuthPlugin::init()
97 97 if (settings.authPluginSerializeInit)
98 98 lock.lock();
99 99  
  100 + if (quitting)
  101 + return;
  102 +
100 103 AuthOptCompatWrap &authOpts = settings.getAuthOptsCompat();
101 104 int result = init_v2(&pluginData, authOpts.head(), authOpts.size());
102 105 if (result != 0)
... ... @@ -125,6 +128,9 @@ void AuthPlugin::securityInit(bool reloading)
125 128 if (settings.authPluginSerializeInit)
126 129 lock.lock();
127 130  
  131 + if (quitting)
  132 + return;
  133 +
128 134 AuthOptCompatWrap &authOpts = settings.getAuthOptsCompat();
129 135 int result = security_init_v2(pluginData, authOpts.head(), authOpts.size(), reloading);
130 136 if (result != 0)
... ... @@ -201,6 +207,11 @@ AuthResult AuthPlugin::unPwdCheck(const std::string &username, const std::string
201 207 return r;
202 208 }
203 209  
  210 +void AuthPlugin::setQuitting()
  211 +{
  212 + this->quitting = true;
  213 +}
  214 +
204 215 std::string AuthResultToString(AuthResult r)
205 216 {
206 217 {
... ...
authplugin.h
... ... @@ -63,6 +63,7 @@ class AuthPlugin
63 63 Logger *logger = nullptr;
64 64 bool initialized = false;
65 65 bool wanted = false;
  66 + bool quitting = false;
66 67  
67 68 void *loadSymbol(void *handle, const char *symbol) const;
68 69 public:
... ... @@ -79,6 +80,8 @@ public:
79 80 AuthResult aclCheck(const std::string &clientid, const std::string &username, const std::string &topic, AclAccess access);
80 81 AuthResult unPwdCheck(const std::string &username, const std::string &password);
81 82  
  83 + void setQuitting();
  84 +
82 85 };
83 86  
84 87 #endif // AUTHPLUGIN_H
... ...
mainapp.cpp
... ... @@ -440,7 +440,12 @@ void MainApp::start()
440 440  
441 441 for(std::shared_ptr<ThreadData> &thread : threads)
442 442 {
443   - thread->quit();
  443 + thread->queueQuit();
  444 + }
  445 +
  446 + for(std::shared_ptr<ThreadData> &thread : threads)
  447 + {
  448 + thread->waitForQuit();
444 449 }
445 450  
446 451 for(auto pair : listenerMap)
... ...
threaddata.cpp
... ... @@ -52,7 +52,6 @@ void ThreadData::start(thread_f f)
52 52 void ThreadData::quit()
53 53 {
54 54 running = false;
55   - thread.join();
56 55 }
57 56  
58 57 void ThreadData::giveClient(Client_p client)
... ... @@ -109,6 +108,23 @@ void ThreadData::queueDoKeepAliveCheck()
109 108 wakeUpThread();
110 109 }
111 110  
  111 +void ThreadData::queueQuit()
  112 +{
  113 + std::lock_guard<std::mutex> locker(taskQueueMutex);
  114 +
  115 + auto f = std::bind(&ThreadData::quit, this);
  116 + taskQueue.push_front(f);
  117 +
  118 + authPlugin.setQuitting();
  119 +
  120 + wakeUpThread();
  121 +}
  122 +
  123 +void ThreadData::waitForQuit()
  124 +{
  125 + thread.join();
  126 +}
  127 +
112 128 // TODO: profile how fast hash iteration is. Perhaps having a second list/vector is beneficial?
113 129 void ThreadData::doKeepAliveCheck()
114 130 {
... ...
threaddata.h
... ... @@ -33,6 +33,7 @@ class ThreadData
33 33 void reload(std::shared_ptr<Settings> settings);
34 34 void wakeUpThread();
35 35 void doKeepAliveCheck();
  36 + void quit();
36 37  
37 38 public:
38 39 Settings settingsLocalCopy; // Is updated on reload, within the thread loop.
... ... @@ -50,7 +51,7 @@ public:
50 51 ThreadData(ThreadData &&other) = delete;
51 52  
52 53 void start(thread_f f);
53   - void quit();
  54 +
54 55 void giveClient(Client_p client);
55 56 Client_p getClient(int fd);
56 57 void removeClient(Client_p client);
... ... @@ -60,6 +61,8 @@ public:
60 61 void initAuthPlugin();
61 62 void queueReload(std::shared_ptr<Settings> settings);
62 63 void queueDoKeepAliveCheck();
  64 + void queueQuit();
  65 + void waitForQuit();
63 66  
64 67 };
65 68  
... ...