diff options
Diffstat (limited to 'src/Net')
-rw-r--r-- | src/Net/ThreadManager.cpp | 31 | ||||
-rw-r--r-- | src/Net/ThreadManager.h | 25 |
2 files changed, 32 insertions, 24 deletions
diff --git a/src/Net/ThreadManager.cpp b/src/Net/ThreadManager.cpp index d24ba01..377e6e1 100644 --- a/src/Net/ThreadManager.cpp +++ b/src/Net/ThreadManager.cpp @@ -59,27 +59,27 @@ void ThreadManager::workerFunc() { } // And let the new worker thread join us... - // TODO pushWork(sigc::bind(sigc::mem_fun(this, &ThreadManager::threadFinished), (gl_thread_t)gl_thread_self())); + pushWork(boost::bind(&ThreadManager::threadFinished, this, boost::this_thread::get_id())); } void ThreadManager::detach() { - if(!isThisMainThread()) { + if(isThisMainThread()) { Common::Logger::log(Common::Logger::CRITICAL, "Tried to detach main thread! This is just WRONG!"); return; } - runLock.lock(); - bool isRunning = running; - runLock.unlock(); - if(!isRunning) // There's no point in creating a new worker thread when we aren't running anymore - return; + { + boost::lock_guard<boost::mutex> lock(runLock); + if(!running) + return; // There's no point in creating a new worker thread when we aren't running anymore + } threadLock.lock(); if(workerThread->get_id() == boost::this_thread::get_id()) {// Already detached? - threads.add_thread(workerThread); + threads.insert(std::make_pair(boost::this_thread::get_id(), workerThread)); - workerThread = new boost::thread(std::mem_fun(&ThreadManager::workerFunc), this); + workerThread.reset(new boost::thread(std::mem_fun(&ThreadManager::workerFunc), this)); } threadLock.unlock(); @@ -102,9 +102,9 @@ void ThreadManager::doInit() { ioWorker.reset(new boost::asio::io_service::work(Connection::ioService)); mainThreadId = boost::this_thread::get_id(); - workerThread = new boost::thread(&ThreadManager::workerFunc, this); - loggerThread = new boost::thread(&Common::LogManager::loggerThread, Common::LogManager::get()); - ioThread = new boost::thread((std::size_t(boost::asio::io_service::*)())&boost::asio::io_service::run, &Connection::ioService); + workerThread.reset(new boost::thread(&ThreadManager::workerFunc, this)); + loggerThread.reset(new boost::thread(&Common::LogManager::loggerThread, Common::LogManager::get())); + ioThread.reset(new boost::thread((std::size_t(boost::asio::io_service::*)())&boost::asio::io_service::run, &Connection::ioService)); threadLock.unlock(); } @@ -126,21 +126,20 @@ void ThreadManager::doDeinit() { // We don't have to lock threadLock as detach() won't change workerThread when running is false workerThread->join(); - delete workerThread; // Now wait for all detached threads - threads.join_all(); + while(!threads.empty()) { + threadFinished(threads.begin()->first); + } // IO thread is next ioWorker.reset(); Connection::ioService.stop(); ioThread->join(); - delete ioThread; // Finally, the logger thread has to die Common::LogManager::get()->stopLoggerThread(); loggerThread->join(); - delete loggerThread; } } diff --git a/src/Net/ThreadManager.h b/src/Net/ThreadManager.h index 2c57747..b8c4bec 100644 --- a/src/Net/ThreadManager.h +++ b/src/Net/ThreadManager.h @@ -25,7 +25,7 @@ #include <Common/Initializable.h> #include <queue> -#include <set> +#include <map> #include <boost/asio.hpp> @@ -39,8 +39,8 @@ namespace Net { class ThreadManager : public Common::Initializable { private: boost::thread::id mainThreadId; - boost::thread *workerThread, *loggerThread, *ioThread; - boost::thread_group threads; + boost::shared_ptr<boost::thread> workerThread, loggerThread, ioThread; + std::map<boost::thread::id, boost::shared_ptr<boost::thread> > threads; boost::mutex threadLock; @@ -60,13 +60,22 @@ class ThreadManager : public Common::Initializable { void workerFunc(); void ioFunc(); - void threadFinished(boost::thread *thread) { - threadLock.lock(); - threads.remove_thread(thread); - threadLock.unlock(); + void threadFinished(boost::thread::id threadId) { + boost::shared_ptr<boost::thread> thread; + + { + boost::lock_guard<boost::mutex> lock(threadLock); + + std::map<boost::thread::id, boost::shared_ptr<boost::thread> >::iterator it = threads.find(threadId); + + if(it == threads.end()) + return; + + thread = it->second; + threads.erase(it); + } thread->join(); - delete thread; } protected: |