Network now closes listener gracefully, meaning threads dont crash anymore, also fixed a minor bug in Game folder
This commit is contained in:
parent
42de421904
commit
a02a32c029
|
@ -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())
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,65 +81,16 @@ 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;
|
||||
|
@ -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)
|
||||
|
@ -385,9 +309,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;
|
||||
}
|
||||
OYSTER_THREAD_ERROR OysterThread::Wait(int msec)
|
||||
|
@ -395,9 +316,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;
|
||||
}
|
||||
OYSTER_THREAD_ERROR OysterThread::Swap(const OysterThread* other)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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?
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue