From aa5a1e6f3f0b462349d7031250d10dd018d29198 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 16 Mar 2026 10:06:06 -0700 Subject: [PATCH] macOS Semaphore Cleanup macOS uses GCD for threading and semaphores. The clients were using semaphore.h or on macOS dispatch.h. This wraps both APIs to remove a bunch of code guards. 1. Add check to configure.ac for presence of dispatch.h. 2. API wrapper checks the header flag from configure to load either dispatch.h or semaphore.h. The check is also the guard for which wrapper to use. 3. Simplify all calls for semaphores into single function calls. --- apps/wolfssh/wolfssh.c | 98 ++++++++++++++++++++++++++++------------ configure.ac | 2 +- examples/client/client.c | 98 ++++++++++++++++++++++++++++------------ 3 files changed, 141 insertions(+), 57 deletions(-) diff --git a/apps/wolfssh/wolfssh.c b/apps/wolfssh/wolfssh.c index 6efbece30..d9a03bd1a 100644 --- a/apps/wolfssh/wolfssh.c +++ b/apps/wolfssh/wolfssh.c @@ -272,22 +272,80 @@ static int sendCurrentWindowSize(thread_args* args) #ifndef _MSC_VER -#if (defined(__OSX__) || defined(__APPLE__)) +#if (defined(__OSX__) || defined(__APPLE__)) \ + && defined(HAVE_DISPATCH_DISPATCH_H) + +/* On a Mac and GCD is available. */ #include -dispatch_semaphore_t windowSem; + +typedef struct { + dispatch_semaphore_t s; +} WOLFSSH_SEMAPHORE; + +static inline +void wolfSSH_SEMAPHORE_Init(WOLFSSH_SEMAPHORE* s, unsigned int n) +{ + s->s = dispatch_semaphore_create((long)n); +} + +static inline +void wolfSSH_SEMAPHORE_Release(WOLFSSH_SEMAPHORE* s) +{ + dispatch_release(s->s); +} + +static inline +void wolfSSH_SEMAPHORE_Wait(WOLFSSH_SEMAPHORE* s) +{ + dispatch_semaphore_wait(s->s, DISPATCH_TIME_FOREVER); +} + +static inline +void wolfSSH_SEMAPHORE_Post(WOLFSSH_SEMAPHORE* s) +{ + dispatch_semaphore_signal(s->s); +} + #else + #include -static sem_t windowSem; + +typedef struct { + sem_t s; +} WOLFSSH_SEMAPHORE; + +static inline +void wolfSSH_SEMAPHORE_Init(WOLFSSH_SEMAPHORE* s, unsigned int n) +{ + sem_init(&s->s, 0, n); +} + +static inline +void wolfSSH_SEMAPHORE_Release(WOLFSSH_SEMAPHORE* s) +{ + sem_destroy(&s->s); +} + +static inline +void wolfSSH_SEMAPHORE_Wait(WOLFSSH_SEMAPHORE* s) +{ + sem_wait(&s->s); +} + +static inline +void wolfSSH_SEMAPHORE_Post(WOLFSSH_SEMAPHORE* s) +{ + sem_post(&s->s); +} + #endif +WOLFSSH_SEMAPHORE windowSem; + /* capture window change signals */ static void WindowChangeSignal(int sig) { -#if (defined(__OSX__) || defined(__APPLE__)) - dispatch_semaphore_signal(windowSem); -#else - sem_post(&windowSem); -#endif + wolfSSH_SEMAPHORE_Post(&windowSem); (void)sig; } @@ -299,11 +357,7 @@ static THREAD_RET windowMonitor(void* in) args = (thread_args*)in; do { - #if (defined(__OSX__) || defined(__APPLE__)) - dispatch_semaphore_wait(windowSem, DISPATCH_TIME_FOREVER); - #else - sem_wait(&windowSem); - #endif + wolfSSH_SEMAPHORE_Wait(&windowSem); if (args->quit) { break; } @@ -1060,11 +1114,7 @@ static THREAD_RETURN WOLFSSH_THREAD wolfSSH_Client(void* args) arg.readError = 0; #ifdef WOLFSSH_TERM arg.quit = 0; - #if (defined(__OSX__) || defined(__APPLE__)) - windowSem = dispatch_semaphore_create(0); - #else - sem_init(&windowSem, 0, 0); - #endif + wolfSSH_SEMAPHORE_Init(&windowSem, 0); if (config.command) { int err; @@ -1087,21 +1137,13 @@ static THREAD_RETURN WOLFSSH_THREAD wolfSSH_Client(void* args) #ifdef WOLFSSH_TERM /* Wake the windowMonitor thread so it can exit. */ arg.quit = 1; - #if (defined(__OSX__) || defined(__APPLE__)) - dispatch_semaphore_signal(windowSem); - #else - sem_post(&windowSem); - #endif + wolfSSH_SEMAPHORE_Post(&windowSem); pthread_join(thread[0], NULL); #endif /* WOLFSSH_TERM */ pthread_cancel(thread[1]); pthread_join(thread[1], NULL); #ifdef WOLFSSH_TERM - #if (defined(__OSX__) || defined(__APPLE__)) - dispatch_release(windowSem); - #else - sem_destroy(&windowSem); - #endif + wolfSSH_SEMAPHORE_Release(&windowSem); #endif /* WOLFSSH_TERM */ ioErr = arg.readError; #elif defined(_MSC_VER) diff --git a/configure.ac b/configure.ac index 09bd6e414..da53cb288 100644 --- a/configure.ac +++ b/configure.ac @@ -56,7 +56,7 @@ AC_TYPE_UINT8_T AC_TYPE_UINTPTR_T # Check headers/libs -AC_CHECK_HEADERS([limits.h sys/select.h sys/time.h sys/ioctl.h pty.h util.h termios.h]) +AC_CHECK_HEADERS([limits.h sys/select.h sys/time.h sys/ioctl.h pty.h util.h termios.h dispatch/dispatch.h]) AC_CHECK_LIB([network],[socket]) AC_CHECK_LIB([util],[forkpty]) diff --git a/examples/client/client.c b/examples/client/client.c index 1eaf951d9..f92f033e6 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -240,22 +240,80 @@ static int sendCurrentWindowSize(thread_args* args) #ifdef WOLFSSH_TERM #ifndef _MSC_VER -#if (defined(__OSX__) || defined(__APPLE__)) +#if (defined(__OSX__) || defined(__APPLE__)) \ + && defined(HAVE_DISPATCH_DISPATCH_H) + +/* On a Mac and GCD is available. */ #include -dispatch_semaphore_t windowSem; + +typedef struct { + dispatch_semaphore_t s; +} WOLFSSH_SEMAPHORE; + +static inline +void wolfSSH_SEMAPHORE_Init(WOLFSSH_SEMAPHORE* s, unsigned int n) +{ + s->s = dispatch_semaphore_create((long)n); +} + +static inline +void wolfSSH_SEMAPHORE_Release(WOLFSSH_SEMAPHORE* s) +{ + dispatch_release(s->s); +} + +static inline +void wolfSSH_SEMAPHORE_Wait(WOLFSSH_SEMAPHORE* s) +{ + dispatch_semaphore_wait(s->s, DISPATCH_TIME_FOREVER); +} + +static inline +void wolfSSH_SEMAPHORE_Post(WOLFSSH_SEMAPHORE* s) +{ + dispatch_semaphore_signal(s->s); +} + #else + #include -static sem_t windowSem; + +typedef struct { + sem_t s; +} WOLFSSH_SEMAPHORE; + +static inline +void wolfSSH_SEMAPHORE_Init(WOLFSSH_SEMAPHORE* s, unsigned int n) +{ + sem_init(&s->s, 0, n); +} + +static inline +void wolfSSH_SEMAPHORE_Release(WOLFSSH_SEMAPHORE* s) +{ + sem_destroy(&s->s); +} + +static inline +void wolfSSH_SEMAPHORE_Wait(WOLFSSH_SEMAPHORE* s) +{ + sem_wait(&s->s); +} + +static inline +void wolfSSH_SEMAPHORE_Post(WOLFSSH_SEMAPHORE* s) +{ + sem_post(&s->s); +} + #endif +WOLFSSH_SEMAPHORE windowSem; + /* capture window change signals */ static void WindowChangeSignal(int sig) { -#if (defined(__OSX__) || defined(__APPLE__)) - dispatch_semaphore_signal(windowSem); -#else - sem_post(&windowSem); -#endif + wolfSSH_SEMAPHORE_Post(&windowSem); (void)sig; } @@ -267,11 +325,7 @@ static THREAD_RET windowMonitor(void* in) args = (thread_args*)in; do { - #if (defined(__OSX__) || defined(__APPLE__)) - dispatch_semaphore_wait(windowSem, DISPATCH_TIME_FOREVER); - #else - sem_wait(&windowSem); - #endif + wolfSSH_SEMAPHORE_Wait(&windowSem); if (args->quit) { break; } @@ -1032,11 +1086,7 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args) arg.quit = 0; wc_InitMutex(&arg.lock); #ifdef WOLFSSH_TERM - #if (defined(__OSX__) || defined(__APPLE__)) - windowSem = dispatch_semaphore_create(0); - #else - sem_init(&windowSem, 0, 0); - #endif + wolfSSH_SEMAPHORE_Init(&windowSem, 0); if (cmd) { int err; @@ -1057,21 +1107,13 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args) #ifdef WOLFSSH_TERM /* Wake the windowMonitor thread so it can exit. */ arg.quit = 1; - #if (defined(__OSX__) || defined(__APPLE__)) - dispatch_semaphore_signal(windowSem); - #else - sem_post(&windowSem); - #endif + wolfSSH_SEMAPHORE_Post(&windowSem); pthread_join(thread[0], NULL); #endif /* WOLFSSH_TERM */ pthread_cancel(thread[1]); pthread_join(thread[1], NULL); #ifdef WOLFSSH_TERM - #if (defined(__OSX__) || defined(__APPLE__)) - dispatch_release(windowSem); - #else - sem_destroy(&windowSem); - #endif + wolfSSH_SEMAPHORE_Release(&windowSem); #endif /* WOLFSSH_TERM */ #elif defined(_MSC_VER) thread_args arg;