diff --git a/server/main.cpp b/server/main.cpp index c9de322..2ad55b5 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -43,3 +43,44 @@ int main(int argc, char** argv) { cout << "Clean exit" << endl; return 0; } +/*/ +#include "thread_safe_queue.hpp" + +#include "SDL/SDL.h" + +#include + +using namespace std; + +struct Object { + int value = 0; +}; + +int func(void* arg) { + ThreadSafeQueue& queue = *reinterpret_cast*>(arg); + while(1) { + Object o = queue.PopFront(); + if (o.value != 0) { + cout << o.value; + SDL_Delay(500); + cout << endl; + } + } +} + +int main(int, char**) { + ThreadSafeQueue queue; + + SDL_Thread* thread1 = SDL_CreateThread(func, reinterpret_cast(&queue)); + SDL_Thread* thread2 = SDL_CreateThread(func, reinterpret_cast(&queue)); + SDL_Thread* thread3 = SDL_CreateThread(func, reinterpret_cast(&queue)); + + while(1) { + SDL_Delay(1000); + Object o; + o.value = 3; + queue.PushBack(o); + } + return 0; +} +//*/ \ No newline at end of file diff --git a/server/network_queue.cpp b/server/network_queue.cpp deleted file mode 100644 index 9601cf9..0000000 --- a/server/network_queue.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright: (c) Kayne Ruse 2013 - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. -*/ -#include "network_queue.hpp" - -#include - -NetworkQueue::NetworkQueue() { - lock = SDL_CreateSemaphore(1); - if (!lock) { - throw(std::runtime_error("Failed to create NetworkQueue::lock")); - } -} - -NetworkQueue::~NetworkQueue() { - SDL_DestroySemaphore(lock); -} - -NetworkPacket NetworkQueue::Push(NetworkPacket packet) { - SDL_SemWait(lock); - queue.push_back(packet); - SDL_SemPost(lock); - return packet; -} - -NetworkPacket NetworkQueue::Peek() { - NetworkPacket ret; - SDL_SemWait(lock); - if (queue.size() > 0) { - ret = queue[0]; - } - SDL_SemPost(lock); - return ret; -} - -NetworkPacket NetworkQueue::Pop() { - NetworkPacket ret; - SDL_SemWait(lock); - if (queue.size() > 0) { - ret = queue[0]; - queue.pop_front(); - } - SDL_SemPost(lock); - return ret; -} - -void NetworkQueue::Flush() { - SDL_SemWait(lock); - queue.clear(); - SDL_SemPost(lock); -} - -int NetworkQueue::Size() { - //can't be sure if std::deque::size() is thread safe - int ret; - SDL_SemWait(lock); - ret = queue.size(); - SDL_SemPost(lock); - return ret; -} \ No newline at end of file diff --git a/server/network_queue.hpp b/server/network_queue.hpp deleted file mode 100644 index bf8924c..0000000 --- a/server/network_queue.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright: (c) Kayne Ruse 2013 - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. -*/ -#ifndef NETWORKQUEUE_HPP_ -#define NETWORKQUEUE_HPP_ - -#include "network_packet.hpp" - -#include "SDL/SDL_thread.h" - -#include - -class NetworkQueue { -public: - NetworkQueue(); - ~NetworkQueue(); - - NetworkPacket Push(NetworkPacket); - NetworkPacket Peek(); - NetworkPacket Pop(); - void Flush(); - - int Size(); - - SDL_sem* GetLock() const { return lock; } -private: - std::deque queue; - SDL_sem* lock; -}; - -#endif diff --git a/server/server_application.cpp b/server/server_application.cpp index 7ce9c0f..bdf8cb4 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -34,7 +34,7 @@ using namespace std; //Declarations //------------------------- -int ServerApplication::ClientEntry::indexCounter = 0; +//int ServerApplication::ClientEntry::indexCounter = 0; //------------------------- //Define the network thread @@ -50,7 +50,7 @@ int networkQueueThread(void* ptr) { memcpy(&packet, app->networkUtil.GetInData(), sizeof(NetworkPacket)); //this is important: keep track of the source address packet.meta.srcAddress = app->networkUtil.GetInPacket()->address; - app->networkQueue.Push(packet); + app->networkQueue.PushBack(packet); } SDL_Delay(10); } @@ -127,7 +127,7 @@ void ServerApplication::Loop() { while(running) { while(networkQueue.Size() > 0) { try { - HandlePacket(networkQueue.Pop()); + HandlePacket(networkQueue.PopFront()); } catch(exception& e) { cerr << "Network Error: " << e.what() << endl; @@ -152,24 +152,24 @@ void ServerApplication::Quit() { void ServerApplication::HandlePacket(NetworkPacket packet) { switch(packet.meta.type) { - case NetworkPacket::Type::PING: - //NOT USED - break; - case NetworkPacket::Type::PONG: - //NOT USED - break; +// case NetworkPacket::Type::PING: +// //NOT USED +// break; +// case NetworkPacket::Type::PONG: +// //NOT USED +// break; case NetworkPacket::Type::BROADCAST_REQUEST: cout << "Recieved a request" << endl; break; - case NetworkPacket::Type::BROADCAST_RESPONSE: - // - break; +// case NetworkPacket::Type::BROADCAST_RESPONSE: +// // +// break; case NetworkPacket::Type::JOIN_REQUEST: // break; - case NetworkPacket::Type::JOIN_RESPONSE: - // - break; +// case NetworkPacket::Type::JOIN_RESPONSE: +// // +// break; case NetworkPacket::Type::DISCONNECT: // break; diff --git a/server/server_application.hpp b/server/server_application.hpp index 19a8bfd..bfa34c1 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -23,7 +23,8 @@ #define SERVERAPPLICATION_HPP_ #include "config_utility.hpp" -#include "network_queue.hpp" +#include "network_packet.hpp" +#include "thread_safe_queue.hpp" #include "udp_network_utility.hpp" #include "world_room.hpp" @@ -31,8 +32,6 @@ #include "SDL/SDL.h" #include "SDL/SDL_thread.h" -#include - //The main application class class ServerApplication { public: @@ -54,19 +53,11 @@ private: //networking UDPNetworkUtility networkUtil; - NetworkQueue networkQueue; + ThreadSafeQueue networkQueue; SDL_Thread* networkQueueThread = nullptr; //database sqlite3* database = nullptr; - - //clients - struct ClientEntry { - static int indexCounter; - int index = indexCounter++; - IPaddress add = {0, 0}; - }; - std::list clientEntries; }; #endif diff --git a/server/thread_safe_queue.hpp b/server/thread_safe_queue.hpp new file mode 100644 index 0000000..128d555 --- /dev/null +++ b/server/thread_safe_queue.hpp @@ -0,0 +1,68 @@ +#ifndef THREADSAFEQUEUE_HPP_ +#define THREADSAFEQUEUE_HPP_ + +#include "SDL/SDL_thread.h" + +#include +#include + +/* This container is a thread safe reimplementation of std::queue. +*/ + +template> +class ThreadSafeQueue { +public: + ThreadSafeQueue() { + lock = SDL_CreateSemaphore(1); + if (!lock) { + throw(std::runtime_error("Failed to create ThreadSafeQueue::lock")); + } + } + + ~ThreadSafeQueue() { + SDL_DestroySemaphore(lock); + } + + T PushBack(T t) { + SDL_SemWait(lock); + container.push_back(t); + SDL_SemPost(lock); + return t; + } + + T PeekFront() { + T t; + SDL_SemWait(lock); + if (container.size() > 0) { + t = container[0]; + } + SDL_SemPost(lock); + return t; + } + + T PopFront() { + T t; + SDL_SemWait(lock); + if (container.size() > 0) { + t = container[0]; + container.pop_front(); + } + SDL_SemPost(lock); + return t; + } + + int Size() { + //can't be sure if std::deque::size() is thread safe + int ret; + SDL_SemWait(lock); + ret = container.size(); + SDL_SemPost(lock); + return ret; + } + +private: + Container container; + SDL_sem* lock; +}; + +#endif diff --git a/server/world_room.hpp b/server/world_room.hpp index 1a9ec15..0a3fc0f 100644 --- a/server/world_room.hpp +++ b/server/world_room.hpp @@ -22,13 +22,8 @@ #ifndef WORLDROOM_HPP_ #define WORLDROOM_HPP_ -#include "config_utility.hpp" -#include "network_queue.hpp" -#include "udp_network_utility.hpp" - -#include "sqlite3/sqlite3.h" -#include "SDL/SDL.h" -#include "SDL/SDL_thread.h" +#include "network_packet.hpp" +#include "thread_safe_queue.hpp" class WorldRoom { public: @@ -39,11 +34,11 @@ public: void Loop(); void Quit(); - NetworkQueue* GetQueue() { return &networkQueue; } + ThreadSafeQueue* GetNetworkQueue() { return &networkQueue; } private: void HandlePacket(NetworkPacket); - NetworkQueue networkQueue; + ThreadSafeQueue networkQueue; }; #endif