diff options
| author | Kai Stevenson <kai@kaistevenson.com> | 2023-03-20 03:51:08 -0700 |
|---|---|---|
| committer | Kai Stevenson <kai@kaistevenson.com> | 2023-03-20 03:51:08 -0700 |
| commit | ad900636080477eb2c8df7a225a71825e5380d3d (patch) | |
| tree | 2fabfebada8ac863b6b4e2e0a128a3146a887be1 /src/fscomch.c | |
| parent | 1a3b3fb05f86e357b099812c0a09a084934fd111 (diff) | |
added proper cancellation token handling; cleanup when host is found to be unresponsive
Diffstat (limited to 'src/fscomch.c')
| -rw-r--r-- | src/fscomch.c | 63 |
1 files changed, 55 insertions, 8 deletions
diff --git a/src/fscomch.c b/src/fscomch.c index 412f9cf..16dcdcf 100644 --- a/src/fscomch.c +++ b/src/fscomch.c @@ -5,8 +5,25 @@ #include <time.h> #include <sys/stat.h> #include <string.h> +#include <pthread.h> #include "fscomch.h" +cancelToken_t init_cancel_token_timeout(int seconds) { + cancelToken_t token; + token.timeout = seconds; + token.value = calloc(1, sizeof(char)); + pthread_t cancelTimer; + cancelToken_t* memToken = malloc(sizeof(cancelToken_t)); + *memToken = token; + pthread_create(&cancelTimer, NULL, cancel_in_secs, (void*)memToken); + return token; +} +cancelToken_t init_cancel_token_never() { + cancelToken_t token; + token.timeout = -1; + token.value = NULL; + return token; +} match_t init_match(char* uuid, FILE* streamIn, FILE* streamOut) { match_t match; match.uuid = uuid; @@ -28,10 +45,10 @@ FILE* try_lock_match() { } return fdopen(fd, "r"); } -match_t await_match(FILE* matchFile, char* cancelToken) { +match_t await_match(FILE* matchFile, cancelToken_t cancelToken) { /* await match UUID */ char* uuid = calloc(37, sizeof(char)); - while (cancelToken == NULL || *cancelToken) { + while (cancelToken.value == NULL || !*cancelToken.value) { if (fgets(uuid, 37, matchFile) != NULL) { break; } @@ -51,7 +68,9 @@ match_t await_match(FILE* matchFile, char* cancelToken) { /* connection complete, delete the match file and the join lock */ remove("/tmp/chess/match"); remove("/tmp/chess/matchjoin"); - return init_match(uuid, streamIn, streamOut); + match_t match = init_match(uuid, streamIn, streamOut); + send_message("ping", match); + return match; } match_t join_match() { /* create a join lock so that no one else can join this match */ @@ -62,6 +81,7 @@ match_t join_match() { match_t match; return match; } + close(fd); /* this is definitely the only process joining the game proceed to generate a uuid */ char* uuid = make_uuid(); @@ -77,17 +97,34 @@ match_t join_match() { FILE* matchFile = fopen("/tmp/chess/match", "a"); fputs(uuid, matchFile); fclose(matchFile); - /* joining match complete, close the descriptor */ - close(fd); - return match; + /* handshake */ + cancelToken_t token = init_cancel_token_timeout(2); + char* message = read_message(match, token); + if (message != NULL) { + if (strcmp(message, "ping") == 0) { + return match; + } + else { + printf("Extreme de-sync. Aborting\n"); + exit(1); + } + } + printf("Host is dead. Cleaning up\n"); + fclose(streamIn); + fclose(streamOut); + remove("/tmp/chess/match"); + remove("/tmp/chess/matchjoin"); + remove(aName); + remove(bName); + exit(1); } void send_message(char* content, match_t match) { fprintf(match.streamOut, "%s\n", content); fflush(match.streamOut); } -char* read_message(match_t match, char* cancelToken) { +char* read_message(match_t match, cancelToken_t cancelToken) { char* buffer = calloc(256, sizeof(char)); - while (cancelToken == NULL || *cancelToken) { + while (cancelToken.value == NULL || !*cancelToken.value) { if (fgets(buffer, 256, match.streamIn) != NULL) { break; } @@ -98,6 +135,11 @@ char* read_message(match_t match, char* cancelToken) { req.tv_nsec = awaitMoveNs; nanosleep(&req, NULL); } + /* if we cancelled via token, return NULL */ + if (cancelToken.value != NULL && *cancelToken.value == 1) { + free(buffer); + return NULL; + } /* overwrite potential newline */ buffer[strlen(buffer) - 1] = '\0'; return buffer; @@ -117,3 +159,8 @@ char* make_uuid() { out[37] = '\0'; return out; } +void* cancel_in_secs(void* token) { + sleep(((cancelToken_t*)token)->timeout); + *(((cancelToken_t*)token)->value) = 1; + free(token); +} |
