summaryrefslogtreecommitdiff
path: root/src/fscomch.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fscomch.c')
-rw-r--r--src/fscomch.c63
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);
+}