Skip to content

Commit 0d1ea6d

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 0d1ea6d

File tree

2 files changed

+113
-62
lines changed

2 files changed

+113
-62
lines changed

apps/wolfssh/wolfssh.c

Lines changed: 56 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -272,22 +272,59 @@ 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+
}
298+
299+
static inline
300+
void wolfSSH_SEMAPHORE_Release(WOLFSSH_SEMAPHORE* s)
301+
{
302+
sem_close(s->s);
303+
sem_unlink(s->name);
304+
}
305+
306+
static inline
307+
int wolfSSH_SEMAPHORE_Wait(WOLFSSH_SEMAPHORE* s)
308+
{
309+
int ret;
310+
do {
311+
ret = sem_wait(s->s);
312+
} while (ret == -1 && errno == EINTR);
313+
return (ret == 0);
314+
}
315+
316+
static inline
317+
void wolfSSH_SEMAPHORE_Post(WOLFSSH_SEMAPHORE* s)
318+
{
319+
sem_post(s->s);
320+
}
321+
322+
static WOLFSSH_SEMAPHORE windowSem;
282323

283324
/* capture window change signals */
284325
static void WindowChangeSignal(int sig)
285326
{
286-
#if (defined(__OSX__) || defined(__APPLE__))
287-
dispatch_semaphore_signal(windowSem);
288-
#else
289-
sem_post(&windowSem);
290-
#endif
327+
wolfSSH_SEMAPHORE_Post(&windowSem);
291328
(void)sig;
292329
}
293330

@@ -299,11 +336,9 @@ static THREAD_RET windowMonitor(void* in)
299336

300337
args = (thread_args*)in;
301338
do {
302-
#if (defined(__OSX__) || defined(__APPLE__))
303-
dispatch_semaphore_wait(windowSem, DISPATCH_TIME_FOREVER);
304-
#else
305-
sem_wait(&windowSem);
306-
#endif
339+
if (!wolfSSH_SEMAPHORE_Wait(&windowSem)) {
340+
break;
341+
}
307342
if (args->quit) {
308343
break;
309344
}
@@ -1060,11 +1095,9 @@ static THREAD_RETURN WOLFSSH_THREAD wolfSSH_Client(void* args)
10601095
arg.readError = 0;
10611096
#ifdef WOLFSSH_TERM
10621097
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
1098+
if (!wolfSSH_SEMAPHORE_Init(&windowSem, 0)) {
1099+
err_sys("Couldn't initialize window semaphore.");
1100+
}
10681101

10691102
if (config.command) {
10701103
int err;
@@ -1087,21 +1120,13 @@ static THREAD_RETURN WOLFSSH_THREAD wolfSSH_Client(void* args)
10871120
#ifdef WOLFSSH_TERM
10881121
/* Wake the windowMonitor thread so it can exit. */
10891122
arg.quit = 1;
1090-
#if (defined(__OSX__) || defined(__APPLE__))
1091-
dispatch_semaphore_signal(windowSem);
1092-
#else
1093-
sem_post(&windowSem);
1094-
#endif
1123+
wolfSSH_SEMAPHORE_Post(&windowSem);
10951124
pthread_join(thread[0], NULL);
10961125
#endif /* WOLFSSH_TERM */
10971126
pthread_cancel(thread[1]);
10981127
pthread_join(thread[1], NULL);
10991128
#ifdef WOLFSSH_TERM
1100-
#if (defined(__OSX__) || defined(__APPLE__))
1101-
dispatch_release(windowSem);
1102-
#else
1103-
sem_destroy(&windowSem);
1104-
#endif
1129+
wolfSSH_SEMAPHORE_Release(&windowSem);
11051130
#endif /* WOLFSSH_TERM */
11061131
ioErr = arg.readError;
11071132
#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)