About to make the processing queue lock properly

This commit is contained in:
2025-04-10 17:14:25 -05:00
parent 1b336ff559
commit 697b5f7ee2
25 changed files with 309 additions and 22 deletions

14
src/packet/CMakeLists.txt Normal file
View File

@ -0,0 +1,14 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_TARGET_NAME}
PRIVATE
packet.c
packetwelcome.c
packetdisconnect.c
packetqueue.c
packetping.c
)

29
src/packet/packet.c Normal file
View File

@ -0,0 +1,29 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "packet.h"
#include "assert/assert.h"
#include "util/memory.h"
void packetInit(
packet_t *packet,
const packettype_t type,
const uint32_t length
) {
assertNotNull(packet, "Packet is NULL");
memoryZero(packet, sizeof(packet_t));
assertTrue(length > 0, "Packet length is 0");
assertTrue(
length <= sizeof(packetdata_t),
"Packet length is too large"
);
packet->type = type;
packet->length = length;
}

45
src/packet/packet.h Normal file
View File

@ -0,0 +1,45 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
#include "packetwelcome.h"
#include "packetdisconnect.h"
#include "packetping.h"
typedef enum {
PACKET_TYPE_INVALID = 0,
PACKET_TYPE_WELCOME = 1,
PACKET_TYPE_DISCONNECT = 2,
PACKET_TYPE_PING = 3,
} packettype_t;
typedef union {
packetwelcome_t welcome;
packetdisconnect_t disconnect;
packetping_t ping;
} packetdata_t;
typedef struct packet_s {
packettype_t type;
uint32_t length;
packetdata_t data;
} packet_t;
/**
* Initializes a packet with the given type. This is only to be used by sub
* initializers, such as packetWelcomeCreate for example.
*
* @param packet Pointer to the packet structure to initialize.
* @param type The type of the packet.
* @param length The length of the packet data.
*/
void packetInit(
packet_t *packet,
const packettype_t type,
const uint32_t length
);

View File

@ -0,0 +1,46 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "packet.h"
#include "util/memory.h"
#include "assert/assert.h"
void packetDisconnectCreate(
packet_t *packet,
const packetdisconnectreason_t reason
) {
packetInit(packet, PACKET_TYPE_DISCONNECT, sizeof(packetdisconnect_t));
packet->data.disconnect.reason = reason;
}
errorret_t packetDisconnectClient(packet_t *packet) {
assertNotNull(packet, "Packet is NULL");
assertTrue(
packet->type == PACKET_TYPE_DISCONNECT,
"Packet type is not DISCONNECT"
);
if(packet->length != sizeof(packetdisconnect_t)) {
return error("Disconnect packet length is not correct");
}
packetdisconnect_t *data = (packetdisconnect_t *)&packet->data;
switch(data->reason) {
case PACKET_DISCONNECT_REASON_UNKNOWN:
return error("Server disconnected: Unknown reason");
case PACKET_DISCONNECT_REASON_INVALID_VERSION:
return error("Server disconnected: Invalid version");
case PACKET_DISCONNECT_REASON_MALFORMED_PACKET:
return error("Server disconnected: Malformed packet");
case PACKET_DISCONNECT_REASON_SERVER_FULL:
return error("Server disconnected: Server full");
case PACKET_DISCONNECT_REASON_SERVER_SHUTDOWN:
return error("Server disconnected: Server shutdown");
default:
return error("Server disconnected: Unknown reason");
}
}

View File

@ -0,0 +1,42 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "error/error.h"
typedef struct packet_s packet_t;
typedef enum {
PACKET_DISCONNECT_REASON_UNKNOWN = 0,
PACKET_DISCONNECT_REASON_INVALID_VERSION = 1,
PACKET_DISCONNECT_REASON_MALFORMED_PACKET = 2,
PACKET_DISCONNECT_REASON_SERVER_FULL = 3,
PACKET_DISCONNECT_REASON_SERVER_SHUTDOWN = 4,
} packetdisconnectreason_t;
typedef struct {
packetdisconnectreason_t reason;
} packetdisconnect_t;
/**
* Creates a disconnect packet.
*
* @param packet Pointer to the packet structure to initialize.
* @param reason The reason for the disconnect.
*/
void packetDisconnectCreate(
packet_t *packet,
const packetdisconnectreason_t reason
);
/**
* Handles a disconnect packet received FROM a server INTO a client.
*
* @param packet Pointer to the packet structure to handle.
* @return ERROR_OK on success, or an error code on failure.
*/
errorret_t packetDisconnectClient(packet_t *packet);

26
src/packet/packetping.c Normal file
View File

@ -0,0 +1,26 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "packet.h"
#include "util/memory.h"
#include "assert/assert.h"
void packetPingCreate(packet_t *packet) {
packetInit(packet, PACKET_TYPE_PING, sizeof(packetping_t));
packet->data.ping.number = GetRandomValue(0, INT32_MAX);
}
errorret_t packetPingClient(packet_t *packet) {
assertNotNull(packet, "Packet is NULL");
assertTrue(packet->type == PACKET_TYPE_PING, "Packet type is not PING");
if(packet->length != sizeof(packetping_t)) {
return error("Ping packet length is not %d", sizeof(packetping_t));
}
return ERROR_OK;
}

28
src/packet/packetping.h Normal file
View File

@ -0,0 +1,28 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "error/error.h"
typedef struct {
int32_t number;
} packetping_t;
/**
* Creates a ping packet.
*
* @param packet Pointer to the packet structure to initialize.
*/
void packetPingCreate(packet_t *packet);
/**
* Handles a ping packet received FROM a server INTO a client.
*
* @param packet Pointer to the packet structure to handle.
* @return ERROR_OK on success, or an error code on failure.
*/
errorret_t packetPingClient(packet_t *packet);

35
src/packet/packetqueue.c Normal file
View File

@ -0,0 +1,35 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "packetqueue.h"
#include "assert/assert.h"
#include "util/memory.h"
void packetQueueInit(packetqueue_t *queue) {
assertNotNull(queue, "Packet queue is NULL");
memoryZero(queue, sizeof(packetqueue_t));
}
void packetQueuePushIn(packetqueue_t *queue, const packet_t *packet) {
assertNotNull(queue, "Packet queue is NULL");
assertNotNull(packet, "Packet is NULL");
assertTrue(
queue->packetsInCount < PACKET_QUEUE_MAX_SIZE, "Packet queue is full"
);
queue->packetsIn[queue->packetsInCount++] = *packet;
}
void packetQueuePushOut(packetqueue_t *queue, const packet_t *packet) {
assertNotNull(queue, "Packet queue is NULL");
assertNotNull(packet, "Packet is NULL");
assertTrue(
queue->packetsOutCount < PACKET_QUEUE_MAX_SIZE, "Packet queue is full"
);
queue->packetsOut[queue->packetsOutCount++] = *packet;
}

49
src/packet/packetqueue.h Normal file
View File

@ -0,0 +1,49 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "packet/packet.h"
#define PACKET_QUEUE_MAX_SIZE 512
typedef struct {
packet_t packetsIn[PACKET_QUEUE_MAX_SIZE];
uint32_t packetsInCount;
packet_t packetsOut[PACKET_QUEUE_MAX_SIZE];
uint32_t packetsOutCount;
// Mutex for thread safety
pthread_mutex_t mutex;
// Condition variables for signaling
pthread_cond_t condIn;
pthread_cond_t condOut;
// Thread ID of the thread that owns the queue
} packetqueue_t;
/**
* Initializes the packet queue.
*
* @param queue Pointer to the packet queue structure.
*/
void packetQueueInit(packetqueue_t *queue);
/**
* Pushes a packet into the inbound packet queue.
*
* @param queue Pointer to the packet queue structure.
* @param packet Pointer to the packet to be pushed.
*/
void packetQueuePushIn(packetqueue_t *queue, const packet_t *packet);
/**
* Pushes a packet from the outbound packet queue.
*
* @param queue Pointer to the packet queue structure.
* @param packet Pointer to the packet to be pushed.
*/
void packetQueuePushOut(packetqueue_t *queue, const packet_t *packet);

View File

@ -0,0 +1,36 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "packet.h"
#include "util/memory.h"
#include "assert/assert.h"
void packetWelcomeCreate(packet_t *packet) {
packetInit(packet, PACKET_TYPE_WELCOME, PACKET_WELCOME_SIZE);
memoryCopy(
packet->data.welcome.dusk, PACKET_WELCOME_STRING, PACKET_WELCOME_SIZE
);
}
errorret_t packetWelcomeClient(packet_t *packet) {
assertNotNull(packet, "Packet is NULL");
assertTrue(packet->type == PACKET_TYPE_WELCOME, "Packet type is not WELCOME");
if(packet->length != PACKET_WELCOME_SIZE) {
return error("Welcome packet length is not %d", PACKET_WELCOME_SIZE);
}
if(
memoryCompare(
packet->data.welcome.dusk, PACKET_WELCOME_STRING, PACKET_WELCOME_SIZE
) != 0
) {
return error("Welcome packet data is not %s", PACKET_WELCOME_STRING);
}
return ERROR_OK;
}

View File

@ -0,0 +1,33 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "error/error.h"
typedef struct packet_s packet_t;
#define PACKET_WELCOME_STRING "DUSK"
#define PACKET_WELCOME_SIZE 4
typedef struct {
char_t dusk[PACKET_WELCOME_SIZE];
} packetwelcome_t;
/**
* Creates a welcome packet.
*
* @param packet Pointer to the packet structure to initialize.
*/
void packetWelcomeCreate(packet_t *packet);
/**
* Handles a welcome packet received FROM a server INTO a client.
*
* @param packet Pointer to the packet structure to handle.
* @return ERROR_OK on success, or an error code on failure.
*/
errorret_t packetWelcomeClient(packet_t *packet);