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 <signal.h>
void* protocolManagerUpdate(void* data)
{
ProtocolManager* manager = static_cast<ProtocolManager*>(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<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;
PlayerLogin m_player_login;
pthread_t* m_protocol_manager_update_thread;
};
#endif // NETWORKMANAGER_HPP

View File

@ -24,6 +24,17 @@
#include <assert.h>
#include <cstdlib>
#include <errno.h>
void* protocolManagerUpdate(void* data)
{
ProtocolManager* manager = static_cast<ProtocolManager*>(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);

View File

@ -198,7 +198,10 @@ class ProtocolManager : public Singleton<ProtocolManager>
/*! \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<ProtocolManager>
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;
};