Skip to content

Commit 3394f02

Browse files
committed
macOS Semaphore Cleanup
macOS uses GCD for threading and semaphores, but they aren't quite like POSIX semaphores. macOS allows the use of named POSIX semaphores. 1. Convert the semaphores to named POSIX semaphores. 2. Simplify all calls for semaphores into single function calls of the wrapper API. 3. Update both examples/client/client.c and apps/wolfssh/wolfssh.c.
1 parent 0103806 commit 3394f02

2 files changed

Lines changed: 114 additions & 62 deletions

File tree

apps/wolfssh/wolfssh.c

Lines changed: 57 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -272,22 +272,60 @@ static int sendCurrentWindowSize(thread_args* args)
272272

273273
#ifndef _MSC_VER
274274

275-
#if (defined(__OSX__) || defined(__APPLE__))
276-
#include <dispatch/dispatch.h>
277-
dispatch_semaphore_t windowSem;
278-
#else
275+
#include <errno.h>
276+
#include <fcntl.h>
279277
#include <semaphore.h>
280-
static sem_t windowSem;
281-
#endif
278+
#include <stdio.h>
279+
#include <unistd.h>
280+
281+
typedef struct {
282+
sem_t* s;
283+
char name[32];
284+
} WOLFSSH_SEMAPHORE;
285+
286+
static inline
287+
int wolfSSH_SEMAPHORE_Init(WOLFSSH_SEMAPHORE* s, unsigned int n)
288+
{
289+
snprintf(s->name, sizeof(s->name), "/wolfssh_winch_%d", (int)getpid());
290+
s->s = sem_open(s->name, O_CREAT | O_EXCL, 0600, n);
291+
if (s->s == SEM_FAILED && errno == EEXIST) {
292+
/* named semaphore already exists, unlink the name and
293+
* try to open it one more time. */
294+
sem_unlink(s->name);
295+
s->s = sem_open(s->name, O_CREAT, 0600, n);
296+
}
297+
return (s->s != SEM_FAILED);
298+
}
299+
300+
static inline
301+
void wolfSSH_SEMAPHORE_Release(WOLFSSH_SEMAPHORE* s)
302+
{
303+
sem_close(s->s);
304+
sem_unlink(s->name);
305+
}
306+
307+
static inline
308+
int wolfSSH_SEMAPHORE_Wait(WOLFSSH_SEMAPHORE* s)
309+
{
310+
int ret;
311+
do {
312+
ret = sem_wait(s->s);
313+
} while (ret == -1 && errno == EINTR);
314+
return (ret == 0);
315+
}
316+
317+
static inline
318+
void wolfSSH_SEMAPHORE_Post(WOLFSSH_SEMAPHORE* s)
319+
{
320+
sem_post(s->s);
321+
}
322+
323+
static WOLFSSH_SEMAPHORE windowSem;
282324

283325
/* capture window change signals */
284326
static void WindowChangeSignal(int sig)
285327
{
286-
#if (defined(__OSX__) || defined(__APPLE__))
287-
dispatch_semaphore_signal(windowSem);
288-
#else
289-
sem_post(&windowSem);
290-
#endif
328+
wolfSSH_SEMAPHORE_Post(&windowSem);
291329
(void)sig;
292330
}
293331

@@ -299,11 +337,9 @@ static THREAD_RET windowMonitor(void* in)
299337

300338
args = (thread_args*)in;
301339
do {
302-
#if (defined(__OSX__) || defined(__APPLE__))
303-
dispatch_semaphore_wait(windowSem, DISPATCH_TIME_FOREVER);
304-
#else
305-
sem_wait(&windowSem);
306-
#endif
340+
if (!wolfSSH_SEMAPHORE_Wait(&windowSem)) {
341+
break;
342+
}
307343
if (args->quit) {
308344
break;
309345
}
@@ -1060,11 +1096,9 @@ static THREAD_RETURN WOLFSSH_THREAD wolfSSH_Client(void* args)
10601096
arg.readError = 0;
10611097
#ifdef WOLFSSH_TERM
10621098
arg.quit = 0;
1063-
#if (defined(__OSX__) || defined(__APPLE__))
1064-
windowSem = dispatch_semaphore_create(0);
1065-
#else
1066-
sem_init(&windowSem, 0, 0);
1067-
#endif
1099+
if (!wolfSSH_SEMAPHORE_Init(&windowSem, 0)) {
1100+
err_sys("Couldn't initialize window semaphore.");
1101+
}
10681102

10691103
if (config.command) {
10701104
int err;
@@ -1087,21 +1121,13 @@ static THREAD_RETURN WOLFSSH_THREAD wolfSSH_Client(void* args)
10871121
#ifdef WOLFSSH_TERM
10881122
/* Wake the windowMonitor thread so it can exit. */
10891123
arg.quit = 1;
1090-
#if (defined(__OSX__) || defined(__APPLE__))
1091-
dispatch_semaphore_signal(windowSem);
1092-
#else
1093-
sem_post(&windowSem);
1094-
#endif
1124+
wolfSSH_SEMAPHORE_Post(&windowSem);
10951125
pthread_join(thread[0], NULL);
10961126
#endif /* WOLFSSH_TERM */
10971127
pthread_cancel(thread[1]);
10981128
pthread_join(thread[1], NULL);
10991129
#ifdef WOLFSSH_TERM
1100-
#if (defined(__OSX__) || defined(__APPLE__))
1101-
dispatch_release(windowSem);
1102-
#else
1103-
sem_destroy(&windowSem);
1104-
#endif
1130+
wolfSSH_SEMAPHORE_Release(&windowSem);
11051131
#endif /* WOLFSSH_TERM */
11061132
ioErr = arg.readError;
11071133
#elif defined(_MSC_VER)

examples/client/client.c

Lines changed: 57 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -240,22 +240,60 @@ static int sendCurrentWindowSize(thread_args* args)
240240
#ifdef WOLFSSH_TERM
241241
#ifndef _MSC_VER
242242

243-
#if (defined(__OSX__) || defined(__APPLE__))
244-
#include <dispatch/dispatch.h>
245-
dispatch_semaphore_t windowSem;
246-
#else
243+
#include <errno.h>
244+
#include <fcntl.h>
247245
#include <semaphore.h>
248-
static sem_t windowSem;
249-
#endif
246+
#include <stdio.h>
247+
#include <unistd.h>
248+
249+
typedef struct {
250+
sem_t* s;
251+
char name[32];
252+
} WOLFSSH_SEMAPHORE;
253+
254+
static inline
255+
int wolfSSH_SEMAPHORE_Init(WOLFSSH_SEMAPHORE* s, unsigned int n)
256+
{
257+
snprintf(s->name, sizeof(s->name), "/wolfssh_winch_%d", (int)getpid());
258+
s->s = sem_open(s->name, O_CREAT | O_EXCL, 0600, n);
259+
if (s->s == SEM_FAILED && errno == EEXIST) {
260+
/* named semaphore already exists, unlink the name and
261+
* try to open it one more time. */
262+
sem_unlink(s->name);
263+
s->s = sem_open(s->name, O_CREAT, 0600, n);
264+
}
265+
return (s->s != SEM_FAILED);
266+
}
267+
268+
static inline
269+
void wolfSSH_SEMAPHORE_Release(WOLFSSH_SEMAPHORE* s)
270+
{
271+
sem_close(s->s);
272+
sem_unlink(s->name);
273+
}
274+
275+
static inline
276+
int wolfSSH_SEMAPHORE_Wait(WOLFSSH_SEMAPHORE* s)
277+
{
278+
int ret;
279+
do {
280+
ret = sem_wait(s->s);
281+
} while (ret == -1 && errno == EINTR);
282+
return (ret == 0);
283+
}
284+
285+
static inline
286+
void wolfSSH_SEMAPHORE_Post(WOLFSSH_SEMAPHORE* s)
287+
{
288+
sem_post(s->s);
289+
}
290+
291+
static WOLFSSH_SEMAPHORE windowSem;
250292

251293
/* capture window change signals */
252294
static void WindowChangeSignal(int sig)
253295
{
254-
#if (defined(__OSX__) || defined(__APPLE__))
255-
dispatch_semaphore_signal(windowSem);
256-
#else
257-
sem_post(&windowSem);
258-
#endif
296+
wolfSSH_SEMAPHORE_Post(&windowSem);
259297
(void)sig;
260298
}
261299

@@ -267,11 +305,9 @@ static THREAD_RET windowMonitor(void* in)
267305

268306
args = (thread_args*)in;
269307
do {
270-
#if (defined(__OSX__) || defined(__APPLE__))
271-
dispatch_semaphore_wait(windowSem, DISPATCH_TIME_FOREVER);
272-
#else
273-
sem_wait(&windowSem);
274-
#endif
308+
if (!wolfSSH_SEMAPHORE_Wait(&windowSem)) {
309+
break;
310+
}
275311
if (args->quit) {
276312
break;
277313
}
@@ -1032,11 +1068,9 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
10321068
arg.quit = 0;
10331069
wc_InitMutex(&arg.lock);
10341070
#ifdef WOLFSSH_TERM
1035-
#if (defined(__OSX__) || defined(__APPLE__))
1036-
windowSem = dispatch_semaphore_create(0);
1037-
#else
1038-
sem_init(&windowSem, 0, 0);
1039-
#endif
1071+
if (!wolfSSH_SEMAPHORE_Init(&windowSem, 0)) {
1072+
err_sys("Couldn't initialize window semaphore.");
1073+
}
10401074

10411075
if (cmd) {
10421076
int err;
@@ -1057,21 +1091,13 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
10571091
#ifdef WOLFSSH_TERM
10581092
/* Wake the windowMonitor thread so it can exit. */
10591093
arg.quit = 1;
1060-
#if (defined(__OSX__) || defined(__APPLE__))
1061-
dispatch_semaphore_signal(windowSem);
1062-
#else
1063-
sem_post(&windowSem);
1064-
#endif
1094+
wolfSSH_SEMAPHORE_Post(&windowSem);
10651095
pthread_join(thread[0], NULL);
10661096
#endif /* WOLFSSH_TERM */
10671097
pthread_cancel(thread[1]);
10681098
pthread_join(thread[1], NULL);
10691099
#ifdef WOLFSSH_TERM
1070-
#if (defined(__OSX__) || defined(__APPLE__))
1071-
dispatch_release(windowSem);
1072-
#else
1073-
sem_destroy(&windowSem);
1074-
#endif
1100+
wolfSSH_SEMAPHORE_Release(&windowSem);
10751101
#endif /* WOLFSSH_TERM */
10761102
#elif defined(_MSC_VER)
10771103
thread_args arg;

0 commit comments

Comments
 (0)