aboutsummaryrefslogtreecommitdiff
path: root/client/libacron/acronc
diff options
context:
space:
mode:
Diffstat (limited to 'client/libacron/acronc')
-rw-r--r--client/libacron/acronc/main.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/client/libacron/acronc/main.c b/client/libacron/acronc/main.c
index 43802ad..dfd1668 100644
--- a/client/libacron/acronc/main.c
+++ b/client/libacron/acronc/main.c
@@ -15,6 +15,65 @@
#endif
+#ifdef __STDC_NO_THREADS__
+# ifdef WIN32
+#define THREAD_WIN32
+#include <windows.h>
+static HANDLE mtx_conn;
+
+int lock(void) { \
+DWORD _dwlck = WaitForSingleObject(mtx_conn, 0); \
+if (_dwlck == WAIT_FAILED) { _dwlck = GetLastError(); } \
+if (_dwlck) { fprintf(stderr, "Cannot lock the mutex: %d.\n", _dwlck); return _dwlck; } \
+return 0; \
+}
+
+int unlock(void) { \
+if (!ReleaseMutex(mtx_conn)) { \
+int r = GetLastError(); \
+fprintf(stderr, "Cannot release the mutex: %d.\n", r); \
+return r; \
+} \
+return 0; \
+}
+
+# else
+#error "Either C11 threading or Win32 API is required for concurrency."
+# endif
+#else
+
+#define THREAD_C11
+
+#include <threads.h>
+
+static mtx_t mtx_conn;
+
+int lock(void) {
+ \
+if (mtx_lock(&mtx_conn) != thrd_success) {
+ \
+fprintf(stderr, "Cannot lock the mutex.\n"); \
+return 1; \
+
+ } \
+return 0; \
+
+}
+
+int unlock(void) {
+ \
+if (mtx_unlock(&mtx_conn) != thrd_success) {
+ \
+fprintf(stderr, "Cannot release the mutex.\n"); \
+return 1; \
+
+ } \
+return 0; \
+
+}
+
+#endif
+
static const char *world_name(const enum ac_world world) {
switch (world) {
case overworld:
@@ -168,6 +227,19 @@ int main(int argc, char **argv) {
if ((r = net_init())) {
return r;
}
+#if defined(THREAD_WIN32)
+ if (!(mtx_conn = CreateMutex(NULL, TRUE, NULL))) {
+ r = GetLastError();
+ fprintf(stderr, "Cannot create mutex: %d.\n", r);
+ return r;
+ }
+#elif defined(THREAD_C11)
+ if (mtx_init(&mtx_conn, mtx_plain) != thrd_success) {
+ fprintf(stderr, "Cannot create mutex.\n");
+ return 1;
+ }
+#endif
+
#ifdef WIN32
fprintf(stderr, "Warning: ^C handler on Windows is not yet available.\n");
#else
@@ -235,12 +307,15 @@ int main(int argc, char **argv) {
goto end;
}
}
+ if ((r = lock())) { goto end; }
if ((r = ac_receive(connection, buffer, bytes, &obj))) {
+ if ((r = unlock())) { goto end; }
goto end;
}
if (!ready) {
/* Wait until ready. */
if ((r = ac_get_state(connection, &state))) {
+ if ((r = unlock())) { goto end; }
goto end;
}
switch (state) {
@@ -250,12 +325,15 @@ int main(int argc, char **argv) {
printf("Connection is established.\n");
ready = true;
say(connection);
+ if ((r = unlock())) { goto end; }
continue;
default:
fprintf(stderr, "Unexpected state.\n");
+ if ((r = unlock())) { goto end; }
goto end;
}
}
+ if ((r = unlock())) { goto end; }
if (!obj) {
continue;
@@ -277,9 +355,16 @@ int main(int argc, char **argv) {
nr);
}
}
+ if ((r = lock())) { goto end; }
ac_disconnect(connection);
+ if ((r = unlock())) { goto end; }
net_close(&sock);
ac_free();
net_free();
+#if defined(THREAD_WIN32)
+ CloseHandle(mtx_conn);
+#elif defined(THREAD_C11)
+ mtx_destroy(&mtx_conn);
+#endif
return r;
} \ No newline at end of file