diff options
Diffstat (limited to 'client/libacron/acronc')
-rw-r--r-- | client/libacron/acronc/main.c | 85 |
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 |