fixing segfault issues when trying to exit, the protocol update thread is now launched by the protocol manager (and not the network manager)

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/networking@13146 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hilnius 2013-07-09 14:07:28 +00:00
parent 008c2d57b2
commit a55016301e
4 changed files with 43 additions and 22 deletions

View File

@ -31,23 +31,12 @@
#include <pthread.h> #include <pthread.h>
#include <signal.h> #include <signal.h>
void* protocolManagerUpdate(void* data)
{
ProtocolManager* manager = static_cast<ProtocolManager*>(data);
while(1)
{
manager->update();
}
return NULL;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
NetworkManager::NetworkManager() NetworkManager::NetworkManager()
{ {
m_public_address.ip = 0; m_public_address.ip = 0;
m_public_address.port = 0; m_public_address.port = 0;
m_protocol_manager_update_thread = NULL;
m_localhost = NULL; m_localhost = NULL;
m_game_setup = NULL; m_game_setup = NULL;
} }
@ -56,11 +45,8 @@ NetworkManager::NetworkManager()
NetworkManager::~NetworkManager() NetworkManager::~NetworkManager()
{ {
if (m_protocol_manager_update_thread)
pthread_cancel(*m_protocol_manager_update_thread);//, SIGKILL);
ProtocolManager::kill(); ProtocolManager::kill();
if (m_localhost) if (m_localhost)
delete m_localhost; delete m_localhost;
while(!m_peers.empty()) while(!m_peers.empty())
@ -73,11 +59,9 @@ NetworkManager::~NetworkManager()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void NetworkManager::run() void NetworkManager::run()
{ {
// create the protocol manager
ProtocolManager::getInstance<ProtocolManager>(); ProtocolManager::getInstance<ProtocolManager>();
m_protocol_manager_update_thread = (pthread_t*)(malloc(sizeof(pthread_t)));
pthread_create(m_protocol_manager_update_thread, NULL, protocolManagerUpdate,
ProtocolManager::getInstance());
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -77,8 +77,6 @@ class NetworkManager : public Singleton<NetworkManager>
TransportAddress m_public_address; TransportAddress m_public_address;
PlayerLogin m_player_login; PlayerLogin m_player_login;
pthread_t* m_protocol_manager_update_thread;
}; };
#endif // NETWORKMANAGER_HPP #endif // NETWORKMANAGER_HPP

View File

@ -24,6 +24,17 @@
#include <assert.h> #include <assert.h>
#include <cstdlib> #include <cstdlib>
#include <errno.h>
void* protocolManagerUpdate(void* data)
{
ProtocolManager* manager = static_cast<ProtocolManager*>(data);
while(!manager->exit())
{
manager->update();
}
return NULL;
}
ProtocolManager::ProtocolManager() ProtocolManager::ProtocolManager()
{ {
@ -31,11 +42,18 @@ ProtocolManager::ProtocolManager()
pthread_mutex_init(&m_protocols_mutex, NULL); pthread_mutex_init(&m_protocols_mutex, NULL);
pthread_mutex_init(&m_requests_mutex, NULL); pthread_mutex_init(&m_requests_mutex, NULL);
pthread_mutex_init(&m_id_mutex, NULL); pthread_mutex_init(&m_id_mutex, NULL);
pthread_mutex_init(&m_exit_mutex, NULL);
m_next_protocol_id = 0; 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() ProtocolManager::~ProtocolManager()
{ {
pthread_mutex_unlock(&m_exit_mutex); // will stop the update function
pthread_mutex_lock(&m_events_mutex); pthread_mutex_lock(&m_events_mutex);
pthread_mutex_lock(&m_protocols_mutex); pthread_mutex_lock(&m_protocols_mutex);
pthread_mutex_lock(&m_requests_mutex); pthread_mutex_lock(&m_requests_mutex);
@ -56,6 +74,7 @@ ProtocolManager::~ProtocolManager()
pthread_mutex_destroy(&m_protocols_mutex); pthread_mutex_destroy(&m_protocols_mutex);
pthread_mutex_destroy(&m_requests_mutex); pthread_mutex_destroy(&m_requests_mutex);
pthread_mutex_destroy(&m_id_mutex); pthread_mutex_destroy(&m_id_mutex);
pthread_mutex_destroy(&m_exit_mutex);
} }
void ProtocolManager::notifyEvent(Event* event) void ProtocolManager::notifyEvent(Event* event)
@ -335,6 +354,18 @@ bool ProtocolManager::isServer()
return NetworkManager::getInstance()->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) void ProtocolManager::assignProtocolId(ProtocolInfo* protocol_info)
{ {
pthread_mutex_lock(&m_id_mutex); pthread_mutex_lock(&m_id_mutex);

View File

@ -198,7 +198,10 @@ class ProtocolManager : public Singleton<ProtocolManager>
/*! \brief Know whether the app is a server. /*! \brief Know whether the app is a server.
* \return True if this application is in server mode, false elseway. * \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:
// protected functions // protected functions
@ -281,6 +284,11 @@ class ProtocolManager : public Singleton<ProtocolManager>
pthread_mutex_t m_requests_mutex; pthread_mutex_t m_requests_mutex;
/*! Used to ensure that the protocol id is used in a thread-safe way.*/ /*! Used to ensure that the protocol id is used in a thread-safe way.*/
pthread_mutex_t m_id_mutex; pthread_mutex_t m_id_mutex;
/*! Used when need to quit.*/
pthread_mutex_t m_exit_mutex;
/*! Update thread.*/
pthread_t* m_update_thread;
}; };