Added and tested the network queue in the server

This is a reimplementation of the old network queue, but using a class.
This still uses a separate thread, so that packets can wait if there's any
lag. Really, thinking about it, I wonder how necessary this was.

On the upside, no singletons this time. Which means that you can have
several instances of UDPNetworkManager. That's unintentional, but good to
know.
This commit is contained in:
Kayne Ruse
2013-11-03 00:22:38 +11:00
parent 54cd26b76f
commit f01463bab3
5 changed files with 176 additions and 1 deletions
+110
View File
@@ -0,0 +1,110 @@
#include "network_queue.hpp"
#include "utility.hpp"
#include <stdexcept>
#include <iostream>
int networkQueueThread(void* ptr) {
NetworkQueue* netQueue = reinterpret_cast<NetworkQueue*>(ptr);
NetworkPacket packet;
while(netQueue->running) {
SDL_SemWait(netQueue->lock);
//suck in the waiting packets
while(netQueue->netUtil->Receive()) {
memcpy(&packet, netQueue->netUtil->GetInData(), sizeof(NetworkPacket));
//this is important: keep track of the source address
packet.meta.srcAddress = netQueue->netUtil->GetInPacket()->address;
netQueue->queue.push_back(packet);
}
SDL_SemPost(netQueue->lock);
SDL_Delay(10);
}
return 0;
}
void NetworkQueue::Init(UDPNetworkUtility* ptr) {
if (running) {
throw(std::runtime_error("Network Queue is already running"));
}
running = true;
netUtil = ptr;
lock = SDL_CreateSemaphore(1);
thread = SDL_CreateThread(networkQueueThread, this);
if (!thread) {
throw(std::runtime_error("Failed to create the network thread"));
}
}
void NetworkQueue::Quit() {
if (!running) {
return;
}
//end the thread
running = false;
int ret;
SDL_WaitThread(thread, &ret);
ResetMembers();
//handle the return
if (ret != 0) {
throw(std::runtime_error(std::string() + "Network thread returned error code: " + to_string_custom(ret)));
}
}
void NetworkQueue::Kill() {
if (!running) {
return;
}
running = false;
SDL_KillThread(thread);
ResetMembers();
}
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);
while(netUtil->Receive());
queue.clear();
SDL_SemPost(lock);
}
void NetworkQueue::ResetMembers() {
if (running) {
throw(std::logic_error("Cannon reset the queue while running"));
}
//reset
netUtil = nullptr;
SDL_DestroySemaphore(lock);
lock = nullptr;
thread = nullptr;
queue.clear();
}
+35
View File
@@ -0,0 +1,35 @@
#ifndef NETWORKQUEUE_HPP_
#define NETWORKQUEUE_HPP_
#include "udp_network_utility.hpp"
#include "network_packet.hpp"
#include "SDL/SDL_thread.h"
#include <deque>
class NetworkQueue {
public:
NetworkQueue() = default;
~NetworkQueue() = default;
void Init(UDPNetworkUtility*);
void Quit();
void Kill();
NetworkPacket Peek();
NetworkPacket Pop();
void Flush();
private:
friend int networkQueueThread(void*);
void ResetMembers();
bool running = false;
UDPNetworkUtility* netUtil = nullptr;
SDL_sem* lock = nullptr;
SDL_Thread* thread = nullptr;
std::deque<NetworkPacket> queue;
};
#endif
+23 -1
View File
@@ -65,6 +65,7 @@ void ServerApplication::Init(int argc, char** argv) {
std::cout << "SDL_net initialized" << std::endl;
}
networkUtil.Open(21795, 1024);
networkQueue.Init(&networkUtil);
//Init SQL
std::string dbname = (argc > 1) ? argv[1] : argv[0];
@@ -89,14 +90,35 @@ void ServerApplication::Init(int argc, char** argv) {
is.close();
sqlite3_exec(database, script.c_str(), nullptr, nullptr, nullptr);
//debugging
//create the debug packets
NetworkPacket packet;
packet.meta.type = NetworkPacket::Type::PING;
strcpy(packet.serverInfo.name,"Foo");
networkUtil.Send("127.0.0.1", 21795, reinterpret_cast<void*>(&packet), sizeof(NetworkPacket));
strcpy(packet.serverInfo.name,"Bar");
networkUtil.Send("127.0.0.1", 21795, reinterpret_cast<void*>(&packet), sizeof(NetworkPacket));
strcpy(packet.serverInfo.name,"World");
networkUtil.Send("127.0.0.1", 21795, reinterpret_cast<void*>(&packet), sizeof(NetworkPacket));
}
void ServerApplication::Loop() {
//
//debugging
SDL_Delay(1000);
NetworkPacket packet;
while(networkQueue.Peek().meta.type != NetworkPacket::Type::NONE) {
packet = networkQueue.Pop();
std::cout << packet.serverInfo.name << std::endl;
};
}
void ServerApplication::Quit() {
sqlite3_close_v2(database);
networkQueue.Quit();
networkUtil.Close();
SDLNet_Quit();
SDL_Quit();
+2
View File
@@ -23,6 +23,7 @@
#define SERVERAPPLICATION_HPP_
#include "udp_network_utility.hpp"
#include "network_queue.hpp"
#include "sqlite3/sqlite3.h"
#include "SDL/SDL.h"
@@ -52,6 +53,7 @@ private:
sqlite3* database = nullptr;
UDPNetworkUtility networkUtil;
NetworkQueue networkQueue;
std::list<ClientEntry> clientEntries;
};