diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2017-05-03 09:48:08 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2017-05-03 09:48:08 -0700 |
commit | 39db45e144275092716ad612d58c7b9ba1bc8eed (patch) | |
tree | e6e6dc484ec779f3e09e1eaee262fcc6153ac3fa | |
parent | 41c187ba12fc05f6e9ccd5f8acbc248c2a3d16e1 (diff) | |
download | infinitytier-39db45e144275092716ad612d58c7b9ba1bc8eed.tar.gz infinitytier-39db45e144275092716ad612d58c7b9ba1bc8eed.zip |
Fix crash on exit (sometimes) in controller.
-rw-r--r-- | controller/EmbeddedNetworkController.cpp | 9 | ||||
-rw-r--r-- | osdep/BlockingQueue.hpp | 27 |
2 files changed, 24 insertions, 12 deletions
diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp index 16839c18..8ff8eb83 100644 --- a/controller/EmbeddedNetworkController.cpp +++ b/controller/EmbeddedNetworkController.cpp @@ -436,19 +436,16 @@ EmbeddedNetworkController::EmbeddedNetworkController(Node *node,const char *dbPa EmbeddedNetworkController::~EmbeddedNetworkController() { - _running = false; std::vector<Thread> t; { Mutex::Lock _l(_threads_m); + _running = false; t = _threads; } if (t.size() > 0) { - for(unsigned long i=0,j=(unsigned long)(t.size() * 4);i<j;++i) - _queue.post((_RQEntry *)0); - /* + _queue.stop(); for(std::vector<Thread>::iterator i(t.begin());i!=t.end();++i) Thread::join(*i); - */ } } @@ -1117,7 +1114,7 @@ void EmbeddedNetworkController::threadMain() { uint64_t lastCircuitTestCheck = 0; _RQEntry *qe = (_RQEntry *)0; - while ((_running)&&((qe = _queue.get()))) { + while ((_running)&&(_queue.get(qe))) { try { if (qe->type == _RQEntry::RQENTRY_TYPE_REQUEST) { _request(qe->nwid,qe->fromAddr,qe->requestPacketId,qe->identity,qe->metaData); diff --git a/osdep/BlockingQueue.hpp b/osdep/BlockingQueue.hpp index 34abcb67..43ae7435 100644 --- a/osdep/BlockingQueue.hpp +++ b/osdep/BlockingQueue.hpp @@ -42,7 +42,7 @@ template <class T> class BlockingQueue { public: - BlockingQueue(void) {} + BlockingQueue(void) : r(true) {} inline void post(T t) { @@ -51,19 +51,34 @@ public: c.notify_one(); } - inline T get(void) + inline void stop(void) + { + std::lock_guard<std::mutex> lock(m); + r = false; + c.notify_all(); + } + + /** + * @param value Value to set to next queue item if return value is true + * @return False if stop() has been called, true otherwise + */ + inline bool get(T &value) { std::unique_lock<std::mutex> lock(m); - while(q.empty()) + if (!r) return false; + while (q.empty()) { c.wait(lock); - T val = q.front(); + if (!r) return false; + } + value = q.front(); q.pop(); - return val; + return true; } private: + volatile bool r; std::queue<T> q; - mutable std::mutex m; + std::mutex m; std::condition_variable c; }; |