diff options
| author | 2025-05-25 18:35:12 -0400 | |
|---|---|---|
| committer | 2025-05-25 18:35:12 -0400 | |
| commit | 9fb3646511998310fc8c967c239803f38b2bdc5b (patch) | |
| tree | 92f1bbc2c7cacfcf0c24b49f88ba220cdeebbde9 | |
| parent | ef86574ec5d859727695da65f683f0774a3b4460 (diff) | |
| download | libnaunet-9fb3646511998310fc8c967c239803f38b2bdc5b.tar.gz libnaunet-9fb3646511998310fc8c967c239803f38b2bdc5b.tar.bz2 libnaunet-9fb3646511998310fc8c967c239803f38b2bdc5b.zip | |
Windows XP support
Signed-off-by: Andrew Opalach <andrew@akon.city>
| -rw-r--r-- | meson.build | 6 | ||||
| -rw-r--r-- | meson_options.txt | 3 | ||||
| -rw-r--r-- | src/util/file/file_stdio.c | 2 | ||||
| -rw-r--r-- | src/util/thread/thread.h | 4 | ||||
| -rw-r--r-- | src/util/thread/thread_windows.c | 59 | ||||
| -rw-r--r-- | src/util/timer/timer_windows.c | 17 | ||||
| -rw-r--r-- | src/winwrap.h | 1 | ||||
| -rw-r--r-- | subprojects/libalabaster.wrap | 2 | ||||
| -rw-r--r-- | tests/condition_variable.c | 39 | ||||
| -rw-r--r-- | tests/meson.build | 1 |
10 files changed, 126 insertions, 8 deletions
diff --git a/meson.build b/meson.build index 74d106d..0622052 100644 --- a/meson.build +++ b/meson.build @@ -114,6 +114,10 @@ endif if is_windows naunet_args += ['-DNAUNET_ON_WINDOWS'] + if get_option('win32-compat') + # https://learn.microsoft.com/en-us/windows/win32/winprog/using-the-windows-headers + naunet_args += ['-DNAUNET_WIN32_COMPAT_MODE'] + endif naunet_src += [ 'src/winwrap.c', 'src/util/timer/timer_windows.c', @@ -153,6 +157,6 @@ naunet = declare_dependency(include_directories: naunet_inc, dependencies: naunet_deps, sources: naunet_src, compile_args: naunet_args) -if get_option('tests') +if get_option('tests').auto() and not meson.is_subproject() subdir('tests') endif diff --git a/meson_options.txt b/meson_options.txt index eb74e99..2c984a4 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,4 +1,5 @@ option('event-loop', type: 'feature', value: 'enabled') option('curl', type: 'feature', value: 'disabled') option('json', type: 'feature', value: 'disabled') -option('tests', type: 'boolean', value: false) +option('win32-compat', type: 'boolean', value: false, yield: true) +option('tests', type: 'feature', value: 'auto', yield: true) diff --git a/src/util/file/file_stdio.c b/src/util/file/file_stdio.c index ae07908..97dd0f0 100644 --- a/src/util/file/file_stdio.c +++ b/src/util/file/file_stdio.c @@ -17,7 +17,7 @@ AL_ASSERT_TYPE_SIZE(off_t, 8); static inline bool open_stdio_file(FILE **file, str *path, const char *mode) { char *c_str = al_str_to_c_str(path); -#ifdef NAUNET_ON_WINDOWS +#if defined NAUNET_ON_WINDOWS && !defined NAUNET_WIN32_COMPAT_MODE // Still sets errno, according to the Microsoft docs. errno_t ret = fopen_s(file, c_str, mode); #else diff --git a/src/util/thread/thread.h b/src/util/thread/thread.h index 6ea5722..142aa3c 100644 --- a/src/util/thread/thread.h +++ b/src/util/thread/thread.h @@ -47,7 +47,11 @@ struct nn_mutex { struct nn_cond { #ifdef NAUNET_ON_WINDOWS +#ifdef NAUNET_WIN32_COMPAT_MODE + HANDLE event; +#else CONDITION_VARIABLE cond; +#endif #else pthread_cond_t cond; #endif diff --git a/src/util/thread/thread_windows.c b/src/util/thread/thread_windows.c index 9ce85e2..8722d0a 100644 --- a/src/util/thread/thread_windows.c +++ b/src/util/thread/thread_windows.c @@ -1,3 +1,5 @@ +#include <al/lib.h> + #include "thread.h" NTSTATUS(__stdcall *NtDelayExecution)(BOOL Alertable, PLARGE_INTEGER DelayInterval); @@ -42,6 +44,28 @@ void nn_thread_detach(struct nn_thread *thread) } */ +/* +void nn_mutex_init(struct nn_mutex *mutex) +{ + mutex->mutex = CreateMutex(NULL, FALSE, NULL); +} + +void nn_mutex_lock(struct nn_mutex *mutex) +{ + WaitForSingleObject(mutex->mutex, INFINITE); +} + +void nn_mutex_unlock(struct nn_mutex *mutex) +{ + ReleaseMutex(mutex->mutex); +} + +void nn_mutex_destroy(struct nn_mutex *mutex) +{ + CloseHandle(mutex->mutex); +} +*/ + void nn_mutex_init(struct nn_mutex *mutex) { InitializeCriticalSection(&mutex->mutex); @@ -62,6 +86,40 @@ void nn_mutex_destroy(struct nn_mutex *mutex) DeleteCriticalSection(&mutex->mutex); } +#ifdef NAUNET_WIN32_COMPAT_MODE +void nn_cond_init(struct nn_cond *cond) +{ + cond->condition = true; + cond->event = CreateEvent(NULL, TRUE, FALSE, NULL); +} + +void nn_cond_wait(struct nn_cond *cond, struct nn_mutex *mutex) +{ + al_assert(cond->condition); + cond->condition = false; + nn_mutex_unlock(mutex); + WaitForSingleObject(cond->event, INFINITE); + ResetEvent(cond->event); + nn_mutex_lock(mutex); +} + +bool nn_cond_is_waiting(struct nn_cond *cond) +{ + return !cond->condition; +} + +void nn_cond_signal(struct nn_cond *cond) +{ + al_assert(!cond->condition); + cond->condition = true; + SetEvent(cond->event); +} + +void nn_cond_destroy(struct nn_cond *cond) +{ + CloseHandle(cond->event); +} +#else void nn_cond_init(struct nn_cond *cond) { cond->condition = true; @@ -91,3 +149,4 @@ void nn_cond_destroy(struct nn_cond *cond) { (void)cond; } +#endif diff --git a/src/util/timer/timer_windows.c b/src/util/timer/timer_windows.c index f26e56a..4ff95ff 100644 --- a/src/util/timer/timer_windows.c +++ b/src/util/timer/timer_windows.c @@ -14,8 +14,17 @@ static const s64 UNIX_TIME_START = 0x019DB1DED53E8000; // January 1st, 1970 in " u64 nn_get_timestamp(void) { - FILETIME ft; - GetSystemTimePreciseAsFileTime(&ft); - return (((LARGE_INTEGER){ .LowPart = ft.dwLowDateTime, .HighPart = ft.dwHighDateTime }).QuadPart - - UNIX_TIME_START) / 10Lu; + FILETIME ft; +#ifdef NAUNET_WIN32_COMPAT_MODE + GetSystemTimeAsFileTime(&ft); +#else + // https://github.com/llvm/llvm-project/commit/3ec634e65a02d5f443cc982e9e00ec4e51143d07 +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8 && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)) || \ + (_WIN32_WINNT >= _WIN32_WINNT_WIN10) + GetSystemTimePreciseAsFileTime(&ft); +#else +#error "GetSystemTimePreciseAsFileTime() requested but not supported." +#endif +#endif + return (((LARGE_INTEGER){ .LowPart = ft.dwLowDateTime, .HighPart = ft.dwHighDateTime }).QuadPart - UNIX_TIME_START) / 10u; } diff --git a/src/winwrap.h b/src/winwrap.h index 0dfa8c6..c97abda 100644 --- a/src/winwrap.h +++ b/src/winwrap.h @@ -2,6 +2,7 @@ #include <al/types.h> +#define _WINSOCK_DEPRECATED_NO_WARNINGS // https://kirkshoop.github.io/2011/09/20/ntstatus.html #include <winsock2.h> #include <ws2tcpip.h> diff --git a/subprojects/libalabaster.wrap b/subprojects/libalabaster.wrap index 6ab8612..2a0e3f4 100644 --- a/subprojects/libalabaster.wrap +++ b/subprojects/libalabaster.wrap @@ -1,4 +1,4 @@ [wrap-git] url = https://git.akon.city/libalabaster -revision = 34a5e136b6c79092eee73857bbad25892fe8047a +revision = 92d5840e1440fe45a150079fab5a39877589c20f depth = 1 diff --git a/tests/condition_variable.c b/tests/condition_variable.c new file mode 100644 index 0000000..6bc5435 --- /dev/null +++ b/tests/condition_variable.c @@ -0,0 +1,39 @@ +#include <al/lib.h> +#include <nnwt/common.h> +#include <nnwt/thread.h> + +static struct nn_mutex mutex; +static struct nn_cond cond; +static struct nn_thread thread; + +static nn_thread_result NNWT_THREADCALL test_thread(void *userdata) +{ + (void)userdata; + + nn_mutex_lock(&mutex); + nn_cond_wait(&cond, &mutex); + nn_mutex_unlock(&mutex); + + return 0; +} + +s32 main(void) +{ + if (!nn_common_init()) return EXIT_FAILURE; + + nn_mutex_init(&mutex); + nn_cond_init(&cond); + + nn_thread_create(&thread, test_thread, NULL); + + nn_thread_sleep(NNWT_TS_FROM_USEC(1000000)); + + nn_mutex_lock(&mutex); + nn_cond_signal(&cond); + // cond_wait() won't return until we unlock here. + nn_mutex_unlock(&mutex); + + nn_thread_join(&thread); + + return EXIT_SUCCESS; +} diff --git a/tests/meson.build b/tests/meson.build index 38b2af8..0482bec 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -2,6 +2,7 @@ executable('timer_thread', ['timer_thread.c'], dependencies: naunet) executable('timer_loop', ['timer_loop.c'], dependencies: naunet) executable('loop_sleep', ['loop_sleep.c'], dependencies: naunet) executable('misc_file', ['misc_file.c'], dependencies: naunet) +executable('condition_variable', ['condition_variable.c'], dependencies: naunet) if not is_windows executable('stdin_lines', ['stdin_lines.c'], dependencies: naunet) executable('fs_event', ['fs_event_local.c'], dependencies: naunet) |