diff --git a/src/network/network_manager.cpp b/src/network/network_manager.cpp index d60d59cc8..463e2b1cf 100644 --- a/src/network/network_manager.cpp +++ b/src/network/network_manager.cpp @@ -31,23 +31,12 @@ #include #include -void* protocolManagerUpdate(void* data) -{ - ProtocolManager* manager = static_cast(data); - while(1) - { - manager->update(); - } - return NULL; -} - //----------------------------------------------------------------------------- NetworkManager::NetworkManager() { m_public_address.ip = 0; m_public_address.port = 0; - m_protocol_manager_update_thread = NULL; m_localhost = NULL; m_game_setup = NULL; } @@ -56,11 +45,8 @@ NetworkManager::NetworkManager() NetworkManager::~NetworkManager() { - if (m_protocol_manager_update_thread) - pthread_cancel(*m_protocol_manager_update_thread);//, SIGKILL); - ProtocolManager::kill(); - + if (m_localhost) delete m_localhost; while(!m_peers.empty()) @@ -73,11 +59,9 @@ NetworkManager::~NetworkManager() //----------------------------------------------------------------------------- void NetworkManager::run() -{ +{ + // create the protocol manager ProtocolManager::getInstance(); - m_protocol_manager_update_thread = (pthread_t*)(malloc(sizeof(pthread_t))); - pthread_create(m_protocol_manager_update_thread, NULL, protocolManagerUpdate, - ProtocolManager::getInstance()); } //----------------------------------------------------------------------------- diff --git a/src/network/network_manager.hpp b/src/network/network_manager.hpp index 456b0930c..1e3673f9c 100644 --- a/src/network/network_manager.hpp +++ b/src/network/network_manager.hpp @@ -77,8 +77,6 @@ class NetworkManager : public Singleton TransportAddress m_public_address; PlayerLogin m_player_login; - - pthread_t* m_protocol_manager_update_thread; }; #endif // NETWORKMANAGER_HPP diff --git a/src/network/protocol_manager.cpp b/src/network/protocol_manager.cpp index c1eeffa09..f2ff081e9 100644 --- a/src/network/protocol_manager.cpp +++ b/src/network/protocol_manager.cpp @@ -24,6 +24,17 @@ #include #include +#include + +void* protocolManagerUpdate(void* data) +{ + ProtocolManager* manager = static_cast(data); + while(!manager->exit()) + { + manager->update(); + } + return NULL; +} ProtocolManager::ProtocolManager() { @@ -31,11 +42,18 @@ ProtocolManager::ProtocolManager() pthread_mutex_init(&m_protocols_mutex, NULL); pthread_mutex_init(&m_requests_mutex, NULL); pthread_mutex_init(&m_id_mutex, NULL); + pthread_mutex_init(&m_exit_mutex, NULL); m_next_protocol_id = 0; + + + pthread_mutex_lock(&m_exit_mutex); // will let the update function run + m_update_thread = (pthread_t*)(malloc(sizeof(pthread_t))); + pthread_create(m_update_thread, NULL, protocolManagerUpdate, this); } ProtocolManager::~ProtocolManager() { + pthread_mutex_unlock(&m_exit_mutex); // will stop the update function pthread_mutex_lock(&m_events_mutex); pthread_mutex_lock(&m_protocols_mutex); pthread_mutex_lock(&m_requests_mutex); @@ -56,6 +74,7 @@ ProtocolManager::~ProtocolManager() pthread_mutex_destroy(&m_protocols_mutex); pthread_mutex_destroy(&m_requests_mutex); pthread_mutex_destroy(&m_id_mutex); + pthread_mutex_destroy(&m_exit_mutex); } void ProtocolManager::notifyEvent(Event* event) @@ -335,6 +354,18 @@ bool ProtocolManager::isServer() return NetworkManager::getInstance()->isServer(); } +int ProtocolManager::exit() +{ + switch(pthread_mutex_trylock(&m_exit_mutex)) { + case 0: /* if we got the lock, unlock and return 1 (true) */ + pthread_mutex_unlock(&m_exit_mutex); + return 1; + case EBUSY: /* return 0 (false) if the mutex was locked */ + return 0; + } + return 1; +} + void ProtocolManager::assignProtocolId(ProtocolInfo* protocol_info) { pthread_mutex_lock(&m_id_mutex); diff --git a/src/network/protocol_manager.hpp b/src/network/protocol_manager.hpp index c8edf9cca..dbb3dc732 100644 --- a/src/network/protocol_manager.hpp +++ b/src/network/protocol_manager.hpp @@ -198,7 +198,10 @@ class ProtocolManager : public Singleton /*! \brief Know whether the app is a server. * \return True if this application is in server mode, false elseway. */ - bool isServer(); + bool isServer(); + + /*! \brief Tells if we need to stop the update thread. */ + int exit(); protected: // protected functions @@ -281,6 +284,11 @@ class ProtocolManager : public Singleton pthread_mutex_t m_requests_mutex; /*! Used to ensure that the protocol id is used in a thread-safe way.*/ pthread_mutex_t m_id_mutex; + /*! Used when need to quit.*/ + pthread_mutex_t m_exit_mutex; + + /*! Update thread.*/ + pthread_t* m_update_thread; };