Network now closes listener gracefully, meaning threads dont crash anymore, also fixed a minor bug in Game folder

This commit is contained in:
Dennis Andersen 2014-01-09 14:18:01 +01:00
parent 42de421904
commit a02a32c029
10 changed files with 101 additions and 126 deletions

View File

@ -96,19 +96,29 @@ namespace DanBias
break;
case protocol_Gameplay_ObjectPosition:
{
Client::GameClientState::ObjPos* protocolData = new Client::GameClientState::ObjPos;
protocolData->object_ID = p[1].value.netInt;
Client::GameClientState::ObjPos protocolData;
protocolData.object_ID = p[1].value.netInt;
for(int i = 0; i< 16; i++)
{
protocolData->worldPos[i] = p[i+2].value.netFloat;
protocolData.worldPos[i] = p[i+2].value.netFloat;
}
if(dynamic_cast<Client::GameState*>(gameClientState))
((Client::GameState*)gameClientState)->Protocol(protocolData);
((Client::GameState*)gameClientState)->Protocol(&protocolData);
delete protocolData;
protocolData = NULL;
//Why use dynamicly allocated memory when data dies after block?
//Client::GameClientState::ObjPos* protocolData = new Client::GameClientState::ObjPos;
//protocolData->object_ID = p[1].value.netInt;
//for(int i = 0; i< 16; i++)
//{
// protocolData->worldPos[i] = p[i+2].value.netFloat;
//}
//
//if(dynamic_cast<Client::GameState*>(gameClientState))
// ((Client::GameState*)gameClientState)->Protocol(protocolData);
//
//delete protocolData;
//protocolData = NULL;
}
break;
@ -159,7 +169,7 @@ namespace DanBias
m_data->recieverObj = new MyRecieverObject;
// m_data->recieverObj->nwClient = new Oyster::Network::NetworkClient(m_data->recieverObj, Oyster::Network::NetworkProtocolCallbackType_Object);
m_data->recieverObj->nwClient = new Oyster::Network::NetworkClient(m_data->recieverObj, Oyster::Network::NetworkProtocolCallbackType_Object);
m_data->recieverObj->nwClient->Connect(desc.port, desc.IP);
if (!m_data->recieverObj->nwClient->IsConnected())

View File

@ -25,7 +25,8 @@ namespace DanBias
void GameServer::NetworkCallback(NetworkClient* client)
{
static GameSession *myTest = 0;
static bool myTest = false;
static int sessionId = -1;
printf("Client with ID [%i] connected.\n", client->GetID());
if(!myTest)
@ -36,10 +37,9 @@ namespace DanBias
desc.mapName = L"test";
desc.clients.Push(c);
desc.exitDestionation = this->mainLobby;
int sessionId = 0;
if((sessionId = GameSessionManager::AddSession(desc, true)) == 0)
printf("Failed to create a game session");
myTest = true;
//myTest = new GameSession();
//
//DanBias::GameSession::GameSessionDescription desc;
@ -52,7 +52,7 @@ namespace DanBias
else
{
Utility::DynamicMemory::SmartPointer<LobbyClient> c = new LobbyClient(client);
myTest->Join(c);
GameSessionManager::JoinSession(sessionId, c);
}
@ -119,6 +119,8 @@ namespace DanBias
}
DanBiasServerReturn GameServer::Release()
{
GameSessionManager::CloseSession();
this->mainLobby->Release();
delete this->mainLobby;
this->server->Shutdown();
delete this->server;

View File

@ -29,6 +29,7 @@ namespace DanBias
return;
}
}
clients.Push(obj);
}
void RemoveObject(DynamicArray<SmartPointer<GameClient>>& clients, DanBias::GameClient* obj)
{
@ -165,10 +166,8 @@ namespace DanBias
if(p[6].value.netBool) //bool bStrafeLeft;
c->GetPlayer()->Move(GameLogic::PLAYER_MOVEMENT_LEFT);
//Oyster::Math::Float4x4 p;
Protocol_ObjectPosition op;//(c.GetPlayer()->GetRigidBody(), c.GetPlayer()->GetID());
//op.object_ID = c.GetPlayer()->GetID();
Send(op.GetProtocol());
//Protocol_ObjectPosition op(c->GetPlayer()->GetOrientation(), c->GetPlayer()->GetID());
//Send(op.GetProtocol());
}
break;
case protocol_Gameplay_PlayerMouseMovement:
@ -197,7 +196,7 @@ namespace DanBias
break;
case GameLogic::Protocol_General_Status::States_disconected:
printf("Client with ID [%i] dissconnected", c->GetClient()->GetID());
printf("Client with ID [%i] dissconnected\n", c->GetClient()->GetID());
RemoveObject(this->clients, c);
break;

View File

@ -78,7 +78,7 @@ bool GameSessionManager::StartSession(int session)
bool GameSessionManager::JoinSession(int session, Utility::DynamicMemory::SmartPointer<LobbyClient> client)
{
int i = -1;
if((i = gameSessionData.Existst(session)) != -1) return false;
if((i = gameSessionData.Existst(session)) == -1) return false;
gameSessionData.sessions[i]->Join(client);
@ -97,6 +97,13 @@ void GameSessionManager::GetSessionInfo(int session, GameSessionInfo& data)
//data.numberOfPlayers = gameSessionData.sessions[i]->
}
void GameSessionManager::CloseSession()
{
for (unsigned int i = 0; i < gameSessionData.sessions.Size(); i++)
{
gameSessionData.sessions[i]->CloseSession();
}
}
void GameSessionManager::CloseSession(int session)
{
int i = -1;

View File

@ -64,6 +64,11 @@ namespace DanBias
*/
static void CloseSession(int session);
/**
* Close all sessions.
*/
static void CloseSession();
/**
* Get total sessions running
* @return Returns the total sessions curently running.

View File

@ -19,11 +19,12 @@ namespace DanBias
}
MainLobby::~MainLobby()
{
delete this->box;
this->box = 0;
}
void MainLobby::Release()
{
delete this->box;
this->box = 0;
this->CloseSession(true);
}

View File

@ -15,8 +15,6 @@ using namespace Oyster::Thread;
using namespace Utility::DynamicMemory;
#pragma region Declerations
enum OYSTER_THREAD_STATE
@ -51,8 +49,8 @@ using namespace Utility::DynamicMemory;
OwnerContainer ownerObj; //
std::atomic<int> msec; //<! A timer in miliseconds.
std::timed_mutex threadFunctionLock;
//std::mutex threadWaitFunctionLock;
//std::timed_mutex threadFunctionLock;
std::mutex threadStopMutex;
};
/** A typical Oyster thread function */
@ -60,8 +58,9 @@ using namespace Utility::DynamicMemory;
struct RefData
{
//std::mutex threadWaitFunctionLock;
std::mutex threadWaitFunctionLock;
bool isCreated;
bool isAlive;
ThreadData *threadData;
std::thread workerThread;
@ -82,69 +81,20 @@ using namespace Utility::DynamicMemory;
this->threadData->state = OYSTER_THREAD_STATE_DEAD;
if(wait)
if(this->workerThread.joinable())
{
if(std::this_thread::get_id() != this->workerThread.get_id())
if(this->workerThread.joinable())
{
this->workerThread.join();
this->isCreated = false;
this->threadData = 0;
}
}
else
{
if(this->workerThread.joinable())
this->workerThread.detach();
this->workerThread.join();
this->isCreated = false;
delete this->threadData;
this->threadData = 0;
}
return OYSTER_THREAD_ERROR_SUCCESS;
}
//OYSTER_THREAD_ERROR Create(ThreadFunction fnc, IThreadObject* worker, bool start, bool detach)
//{
// if(this->isCreated ) return OYSTER_THREAD_ERROR_ThreadAlreadyCreated;
//
// threadData = new ThreadData();
// if(start)
// this->threadData->state = OYSTER_THREAD_STATE_NORMAL;
// else
// this->threadData->state = OYSTER_THREAD_STATE_IDLE;
// threadData->owner = worker;
// threadData->prio = OYSTER_THREAD_PRIORITY_3;
//
// workerThread = std::thread(fnc, this->threadData);
//
// if(detach)
// this->workerThread.detach();
//
// isCreated = true;
//
// return OYSTER_THREAD_ERROR_SUCCESS;
//}
//OYSTER_THREAD_ERROR Create(ThreadFunction fnc, Oyster::Callback::OysterCallback<bool, void> worker, bool start, bool detach)
//{
// if(this->isCreated ) return OYSTER_THREAD_ERROR_ThreadAlreadyCreated;
//
// threadData = new ThreadData();
// if(start)
// this->threadData->state = OYSTER_THREAD_STATE_NORMAL;
// else
// this->threadData->state = OYSTER_THREAD_STATE_IDLE;
// threadData->ownerObj = worker;
// threadData->prio = OYSTER_THREAD_PRIORITY_3;
//
// workerThread = std::thread(fnc, this->threadData);
//
// if(detach)
// this->workerThread.detach();
//
// isCreated = true;
//
// return OYSTER_THREAD_ERROR_SUCCESS;
//}
OYSTER_THREAD_ERROR Create(ThreadFunction fnc, OwnerContainer worker, bool start, bool detach)
{
if(this->isCreated ) return OYSTER_THREAD_ERROR_ThreadAlreadyCreated;
threadData = new ThreadData();
if(start)
this->threadData->state = OYSTER_THREAD_STATE_NORMAL;
@ -155,8 +105,8 @@ using namespace Utility::DynamicMemory;
workerThread = std::thread(fnc, this->threadData);
if(detach)
this->workerThread.detach();
//if(detach)
// this->workerThread.detach();
isCreated = true;
@ -171,9 +121,7 @@ using namespace Utility::DynamicMemory;
PrivateData(){}
~PrivateData()
{
if(data)
if(data->threadData)
memset(&data->threadData->ownerObj, 0, sizeof(OwnerContainer));
data.Release();
}
OYSTER_THREAD_ERROR Create(ThreadFunction fnc, OwnerContainer worker, bool start, bool detach)
{
@ -248,7 +196,8 @@ using namespace Utility::DynamicMemory;
if(w->ownerObj.value.obj) w->ownerObj.value.obj->ThreadExit();
w->state = OYSTER_THREAD_STATE_DEAD;
delete w;
//delete w;
}
};
@ -295,31 +244,6 @@ OYSTER_THREAD_ERROR OysterThread::Create(ThreadFnc worker, bool start, bool deta
return this->privateData->Create(ThreadHelp::ThreadingFunction, c, start, detach);
}
/*
OYSTER_THREAD_ERROR OysterThread::Create(Oyster::Callback::CallbackObject<bool, void>* worker, bool start, bool detach)
{
if(!this->privateData)
this->privateData = new PrivateData();
Oyster::Callback::OysterCallback<> temp;
temp.callbackType = Oyster::Callback::CallbackType_Object;
temp.value = worker;
return this->privateData->Create(ThreadHelp::ThreadingFunction, temp, start, detach);
}
OYSTER_THREAD_ERROR OysterThread::Create(Oyster::Callback::CallbackFunction<bool, void>::FNC worker, bool start, bool detach)
{
if(!this->privateData)
this->privateData = new PrivateData();
Oyster::Callback::OysterCallback<> temp;
temp.callbackType = Oyster::Callback::CallbackType_Function;
temp.value = worker;
return this->privateData->Create(ThreadHelp::ThreadingFunction, temp, start, detach);
}
*/
OYSTER_THREAD_ERROR OysterThread::Start()
{
if(!this->privateData->data->threadData->ownerObj)
@ -384,9 +308,6 @@ OYSTER_THREAD_ERROR OysterThread::Wait()
if( this->privateData->data->workerThread.get_id() == std::this_thread::get_id())
return OYSTER_THREAD_ERROR_ThreadCannotWaintOnItselfe;
//this->privateData->data->threadData->threadFunctionLock.lock();
//this->privateData->data->threadData->threadFunctionLock.unlock();
return OYSTER_THREAD_ERROR_SUCCESS;
}
@ -394,9 +315,6 @@ OYSTER_THREAD_ERROR OysterThread::Wait(int msec)
{
if(this->privateData->data->workerThread.get_id() == std::this_thread::get_id())
return OYSTER_THREAD_ERROR_ThreadCannotWaintOnItselfe;
//if(this->privateData->data->threadData->threadFunctionLock.try_lock_for(std::chrono::milliseconds(msec)))
// this->privateData->data->threadData->threadFunctionLock.unlock();
return OYSTER_THREAD_ERROR_SUCCESS;
}

View File

@ -63,9 +63,8 @@ struct ClientDataContainer
}
~ClientDataContainer()
{
thread.Stop();
thread.Wait();
connection.Disconnect();
thread.Stop();
callbackType = NetworkProtocolCallbackType_Unknown;
ShutdownWinSock();
@ -244,6 +243,7 @@ bool NetworkClient::Connect(unsigned short port, const char serverIP[])
void NetworkClient::Disconnect()
{
privateData->data->connection.Disconnect();
privateData->data->thread.Terminate();
}
bool NetworkClient::IsConnected()

View File

@ -6,11 +6,14 @@ using namespace Oyster::Thread;
Listener::Listener()
{
this->port = -1;
this->isListening = false;
connection = NULL;
}
Listener::Listener(Oyster::Network::IPostBox<int>* postBox)
{
this->isListening = false;
connection = NULL;
this->postBox = postBox;
}
@ -19,9 +22,11 @@ Listener::~Listener()
{
if(connection)
{
this->thread.Terminate(false);
this->isListening = false;
this->thread.Terminate();
delete connection;
connection = 0;
this->port = -1;
}
}
@ -36,6 +41,8 @@ bool Listener::Init(unsigned int port)
return false;
}
this->port = port;
this->isListening = true;
return true;
}
@ -52,6 +59,11 @@ bool Listener::Init(unsigned int port, bool start)
return false;
}
if(start)
{
this->isListening = true;
}
this->port = port;
return true;
}
@ -62,17 +74,18 @@ bool Listener::Start()
return false;
}
this->isListening = true;
return true;
}
void Listener::Stop()
{
thread.Stop();
StopListen();
}
void Listener::Shutdown()
{
thread.Stop(false);
StopListen();
}
void Listener::SetPostBox(Oyster::Network::IPostBox<int>* postBox)
@ -87,6 +100,10 @@ int Listener::Accept()
int clientSocket = -1;
clientSocket = connection->Listen();
if(!this->isListening.load())
{
return -1;
}
if(clientSocket != -1)
{
stdMutex.lock();
@ -96,13 +113,26 @@ int Listener::Accept()
return clientSocket;
}
void Listener::StopListen()
{
if(this->connection && this->connection->IsConnected())
{
this->isListening = false;
Connection c;
c.InitiateClient();
c.Connect(this->port, "127.0.0.1");
}
}
bool Listener::DoWork()
{
if(!this->connection) return false;
int result = Accept();
if(result == -1)
if(!this->isListening.load())
{
return false;
}
else if(result == -1)
{
//Do something?
}

View File

@ -11,6 +11,7 @@
#include "../../Misc/Thread/OysterThread.h"
#include "../../Misc/Thread/OysterMutex.h"
#include "../../Misc/Utilities.h"
#include <atomic>
namespace Oyster
{
@ -41,6 +42,7 @@ namespace Oyster
//Function that runs in the thread.
int Accept();
void StopListen();
private:
::Oyster::Network::Connection* connection;
@ -50,7 +52,8 @@ namespace Oyster
std::mutex stdMutex;
IPostBox<int>* postBox;
std::atomic<bool> isListening;
int port;
};
}
}