Просмотр исходного кода

Fix crash on exit (sometimes) in controller.

Adam Ierymenko 8 лет назад
Родитель
Сommit
39db45e144
2 измененных файлов с 24 добавлено и 12 удалено
  1. 3 6
      controller/EmbeddedNetworkController.cpp
  2. 21 6
      osdep/BlockingQueue.hpp

+ 3 - 6
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);

+ 21 - 6
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;
 };