simulation thread created and socket response handler actually uses the mutex now
This commit is contained in:
parent
693c238664
commit
307323e561
@ -1,6 +1,10 @@
|
|||||||
#ifndef ERROR_H
|
#ifndef ERROR_H
|
||||||
#define ERROR_H
|
#define ERROR_H
|
||||||
|
|
||||||
|
// TODO: Most of these aren't even errors used in this library.
|
||||||
|
// I should trim this down to only the ones belonging to the library, and make
|
||||||
|
// new enums for the client and server. Perhaps I can leverage __ERR_COUNT to
|
||||||
|
// have the client/server-specific enums start where this one ends
|
||||||
enum error_t {
|
enum error_t {
|
||||||
ERR_OK,
|
ERR_OK,
|
||||||
ERR_INPUT,
|
ERR_INPUT,
|
||||||
@ -14,6 +18,7 @@ enum error_t {
|
|||||||
ERR_INVALID_REQUEST,
|
ERR_INVALID_REQUEST,
|
||||||
ERR_REQUEST_FAILED,
|
ERR_REQUEST_FAILED,
|
||||||
ERR_THREAD,
|
ERR_THREAD,
|
||||||
|
ERR_MUTEX,
|
||||||
__ERR_COUNT,
|
__ERR_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,7 +14,8 @@ char const *const ERROR_STRS[] = {
|
|||||||
"JSON DESERIALISATION",
|
"JSON DESERIALISATION",
|
||||||
"INVALID REQUEST",
|
"INVALID REQUEST",
|
||||||
"REQUEST FAILED",
|
"REQUEST FAILED",
|
||||||
"THREAD INITIALISATION"
|
"THREAD INITIALISATION",
|
||||||
|
"MUTEX ERROR",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
// main.c
|
// main.c
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -23,6 +24,34 @@ static void handle_signal(int signal_no) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static enum error_t simulation_thread_body(struct game_data_t *data) {
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
// TODO: An actual game loop lol
|
||||||
|
printf("Hello, world!\n");
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static enum error_t simulation_thread(
|
||||||
|
pthread_t *pthread,
|
||||||
|
struct game_data_t *data
|
||||||
|
) {
|
||||||
|
assert(pthread != NULL);
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
int err = pthread_create(
|
||||||
|
pthread, NULL,
|
||||||
|
(void *(*)(void *))simulation_thread_body, data
|
||||||
|
);
|
||||||
|
if (err != 0) return ERR_THREAD;
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
// Set up variables
|
// Set up variables
|
||||||
enum error_t err = ERR_OK;
|
enum error_t err = ERR_OK;
|
||||||
@ -60,11 +89,18 @@ int main(int argc, char **argv) {
|
|||||||
entity_init(&data.world.entities[26], 2, 2, 6);
|
entity_init(&data.world.entities[26], 2, 2, 6);
|
||||||
// Make a gap in the entity array to see if "ghost" entities remain
|
// Make a gap in the entity array to see if "ghost" entities remain
|
||||||
|
|
||||||
// Socket handling
|
// Socket handler thread
|
||||||
pthread_t pthread_socket;
|
pthread_t pthread_socket;
|
||||||
err = socket_thread(&pthread_socket, &data);
|
err = socket_thread(&pthread_socket, &data);
|
||||||
if (err) goto handle_error;
|
if (err) goto handle_error;
|
||||||
|
|
||||||
|
// Simulation thread
|
||||||
|
pthread_t pthread_simulation;
|
||||||
|
err = simulation_thread(&pthread_simulation, &data);
|
||||||
|
if (err) goto handle_error;
|
||||||
|
|
||||||
|
// Join threads
|
||||||
|
// TODO: A way to shut down the program properly
|
||||||
pthread_join(pthread_socket, (void **)&err); // No way this is correct lol
|
pthread_join(pthread_socket, (void **)&err); // No way this is correct lol
|
||||||
if (err) goto handle_error;
|
if (err) goto handle_error;
|
||||||
|
|
||||||
|
@ -4,10 +4,18 @@
|
|||||||
|
|
||||||
#include "request.h"
|
#include "request.h"
|
||||||
|
|
||||||
|
static struct response_t response_failure(
|
||||||
|
struct request_t const *request
|
||||||
|
) {
|
||||||
|
assert(request != NULL);
|
||||||
|
|
||||||
|
return (struct response_t){ request->type, false, NULL };
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_request_get_world_data(
|
static void handle_request_get_world_data(
|
||||||
struct response_t *response,
|
struct response_t *response,
|
||||||
struct request_t const *request,
|
struct request_t const *request,
|
||||||
struct game_data_t const *ctx
|
struct game_data_t *ctx
|
||||||
) {
|
) {
|
||||||
assert(response != NULL);
|
assert(response != NULL);
|
||||||
assert(request != NULL);
|
assert(request != NULL);
|
||||||
@ -16,11 +24,24 @@ static void handle_request_get_world_data(
|
|||||||
// TODO: World creation isn't set up yet, so the world-id parameter isn't
|
// TODO: World creation isn't set up yet, so the world-id parameter isn't
|
||||||
// useful right now, but make sure to use it later when it is set up
|
// useful right now, but make sure to use it later when it is set up
|
||||||
|
|
||||||
struct response_body_get_world_data_t *body = response->body;
|
struct response_body_get_world_data_t *body =
|
||||||
|
malloc(sizeof(struct response_body_get_world_data_t));
|
||||||
|
if (body == NULL) goto error;
|
||||||
|
|
||||||
|
response->body = body;
|
||||||
|
|
||||||
|
if (pthread_mutex_lock(&ctx->world_lock) != 0) goto error;
|
||||||
body->world = ctx->world;
|
body->world = ctx->world;
|
||||||
|
if (pthread_mutex_unlock(&ctx->world_lock) != 0) goto error;
|
||||||
|
|
||||||
response->type = request->type;
|
response->type = request->type;
|
||||||
response->success = true;
|
response->success = true;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
error:
|
||||||
|
free(body);
|
||||||
|
*response = response_failure(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -35,14 +56,10 @@ struct response_t handle_request(
|
|||||||
|
|
||||||
switch (request->type) {
|
switch (request->type) {
|
||||||
case REQUEST_GET_WORLD_DATA:
|
case REQUEST_GET_WORLD_DATA:
|
||||||
response.body = malloc(sizeof(struct response_body_get_world_data_t));
|
|
||||||
if (response.body == NULL)
|
|
||||||
return (struct response_t){ request->type, false, NULL };
|
|
||||||
|
|
||||||
handle_request_get_world_data(&response, request, ctx);
|
handle_request_get_world_data(&response, request, ctx);
|
||||||
return response;
|
return response;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return (struct response_t){ 0 };
|
return response_failure(request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,14 +67,12 @@ static enum error_t socket_handle(struct game_data_t *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *socket_thread_body(void *data_void) {
|
static enum error_t socket_thread_body(struct game_data_t *data) {
|
||||||
assert(data_void != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
struct game_data_t *data = (struct game_data_t *)data_void;
|
|
||||||
|
|
||||||
enum error_t err = ERR_OK;
|
enum error_t err = ERR_OK;
|
||||||
|
|
||||||
if ((err = socket_init(&data->socket))) return (void *)err;
|
if ((err = socket_init(&data->socket))) return err;
|
||||||
|
|
||||||
for (int sock_accept;;) {
|
for (int sock_accept;;) {
|
||||||
if ((sock_accept = accept(data->socket, NULL, NULL)) < 0) {
|
if ((sock_accept = accept(data->socket, NULL, NULL)) < 0) {
|
||||||
@ -95,12 +93,19 @@ error_pre:
|
|||||||
|
|
||||||
error:
|
error:
|
||||||
socket_free(&data->socket);
|
socket_free(&data->socket);
|
||||||
return (void *)err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum error_t socket_thread(pthread_t *pthread, struct game_data_t *data) {
|
enum error_t socket_thread(pthread_t *pthread, struct game_data_t *data) {
|
||||||
int err = pthread_create(pthread, NULL, socket_thread_body, data);
|
assert(pthread != NULL);
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
int err = pthread_create(
|
||||||
|
pthread, NULL,
|
||||||
|
(void *(*)(void *))socket_thread_body, // I want to cry tf is this
|
||||||
|
data
|
||||||
|
);
|
||||||
if (err != 0) return ERR_THREAD;
|
if (err != 0) return ERR_THREAD;
|
||||||
|
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
|
Loading…
Reference in New Issue
Block a user