Skip to content

Commit c09d21f

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. 4. Update both to deregister the WINCH signal.
1 parent 0103806 commit c09d21f

File tree

2 files changed

+122
-62
lines changed

2 files changed

+122
-62
lines changed

apps/wolfssh/wolfssh.c

Lines changed: 61 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -272,22 +272,63 @@ 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+
if (s != NULL && s->s != NULL && s->s != SEM_FAILED) {
304+
sem_close(s->s);
305+
sem_unlink(s->name);
306+
s->s = NULL;
307+
}
308+
}
309+
310+
static inline
311+
int wolfSSH_SEMAPHORE_Wait(WOLFSSH_SEMAPHORE* s)
312+
{
313+
int ret;
314+
do {
315+
ret = sem_wait(s->s);
316+
} while (ret == -1 && errno == EINTR);
317+
return (ret == 0);
318+
}
319+
320+
static inline
321+
void wolfSSH_SEMAPHORE_Post(WOLFSSH_SEMAPHORE* s)
322+
{
323+
sem_post(s->s);
324+
}
325+
326+
static WOLFSSH_SEMAPHORE windowSem;
282327

283328
/* capture window change signals */
284329
static void WindowChangeSignal(int sig)
285330
{
286-
#if (defined(__OSX__) || defined(__APPLE__))
287-
dispatch_semaphore_signal(windowSem);
288-
#else
289-
sem_post(&windowSem);
290-
#endif
331+
wolfSSH_SEMAPHORE_Post(&windowSem);
291332
(void)sig;
292333
}
293334

@@ -299,11 +340,9 @@ static THREAD_RET windowMonitor(void* in)
299340

300341
args = (thread_args*)in;
301342
do {
302-
#if (defined(__OSX__) || defined(__APPLE__))
303-
dispatch_semaphore_wait(windowSem, DISPATCH_TIME_FOREVER);
304-
#else
305-
sem_wait(&windowSem);
306-
#endif
343+
if (!wolfSSH_SEMAPHORE_Wait(&windowSem)) {
344+
break;
345+
}
307346
if (args->quit) {
308347
break;
309348
}
@@ -1060,11 +1099,9 @@ static THREAD_RETURN WOLFSSH_THREAD wolfSSH_Client(void* args)
10601099
arg.readError = 0;
10611100
#ifdef WOLFSSH_TERM
10621101
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
1102+
if (!wolfSSH_SEMAPHORE_Init(&windowSem, 0)) {
1103+
err_sys("Couldn't initialize window semaphore.");
1104+
}
10681105

10691106
if (config.command) {
10701107
int err;
@@ -1087,21 +1124,14 @@ static THREAD_RETURN WOLFSSH_THREAD wolfSSH_Client(void* args)
10871124
#ifdef WOLFSSH_TERM
10881125
/* Wake the windowMonitor thread so it can exit. */
10891126
arg.quit = 1;
1090-
#if (defined(__OSX__) || defined(__APPLE__))
1091-
dispatch_semaphore_signal(windowSem);
1092-
#else
1093-
sem_post(&windowSem);
1094-
#endif
1127+
signal(SIGWINCH, SIG_DFL);
1128+
wolfSSH_SEMAPHORE_Post(&windowSem);
10951129
pthread_join(thread[0], NULL);
10961130
#endif /* WOLFSSH_TERM */
10971131
pthread_cancel(thread[1]);
10981132
pthread_join(thread[1], NULL);
10991133
#ifdef WOLFSSH_TERM
1100-
#if (defined(__OSX__) || defined(__APPLE__))
1101-
dispatch_release(windowSem);
1102-
#else
1103-
sem_destroy(&windowSem);
1104-
#endif
1134+
wolfSSH_SEMAPHORE_Release(&windowSem);
11051135
#endif /* WOLFSSH_TERM */
11061136
ioErr = arg.readError;
11071137
#elif defined(_MSC_VER)

examples/client/client.c

Lines changed: 61 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -240,22 +240,63 @@ 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+
if (s != NULL && s->s != NULL && s->s != SEM_FAILED) {
272+
sem_close(s->s);
273+
sem_unlink(s->name);
274+
s->s = NULL;
275+
}
276+
}
277+
278+
static inline
279+
int wolfSSH_SEMAPHORE_Wait(WOLFSSH_SEMAPHORE* s)
280+
{
281+
int ret;
282+
do {
283+
ret = sem_wait(s->s);
284+
} while (ret == -1 && errno == EINTR);
285+
return (ret == 0);
286+
}
287+
288+
static inline
289+
void wolfSSH_SEMAPHORE_Post(WOLFSSH_SEMAPHORE* s)
290+
{
291+
sem_post(s->s);
292+
}
293+
294+
static WOLFSSH_SEMAPHORE windowSem;
250295

251296
/* capture window change signals */
252297
static void WindowChangeSignal(int sig)
253298
{
254-
#if (defined(__OSX__) || defined(__APPLE__))
255-
dispatch_semaphore_signal(windowSem);
256-
#else
257-
sem_post(&windowSem);
258-
#endif
299+
wolfSSH_SEMAPHORE_Post(&windowSem);
259300
(void)sig;
260301
}
261302

@@ -267,11 +308,9 @@ static THREAD_RET windowMonitor(void* in)
267308

268309
args = (thread_args*)in;
269310
do {
270-
#if (defined(__OSX__) || defined(__APPLE__))
271-
dispatch_semaphore_wait(windowSem, DISPATCH_TIME_FOREVER);
272-
#else
273-
sem_wait(&windowSem);
274-
#endif
311+
if (!wolfSSH_SEMAPHORE_Wait(&windowSem)) {
312+
break;
313+
}
275314
if (args->quit) {
276315
break;
277316
}
@@ -1032,11 +1071,9 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
10321071
arg.quit = 0;
10331072
wc_InitMutex(&arg.lock);
10341073
#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
1074+
if (!wolfSSH_SEMAPHORE_Init(&windowSem, 0)) {
1075+
err_sys("Couldn't initialize window semaphore.");
1076+
}
10401077

10411078
if (cmd) {
10421079
int err;
@@ -1057,21 +1094,14 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
10571094
#ifdef WOLFSSH_TERM
10581095
/* Wake the windowMonitor thread so it can exit. */
10591096
arg.quit = 1;
1060-
#if (defined(__OSX__) || defined(__APPLE__))
1061-
dispatch_semaphore_signal(windowSem);
1062-
#else
1063-
sem_post(&windowSem);
1064-
#endif
1097+
signal(SIGWINCH, SIG_DFL);
1098+
wolfSSH_SEMAPHORE_Post(&windowSem);
10651099
pthread_join(thread[0], NULL);
10661100
#endif /* WOLFSSH_TERM */
10671101
pthread_cancel(thread[1]);
10681102
pthread_join(thread[1], NULL);
10691103
#ifdef WOLFSSH_TERM
1070-
#if (defined(__OSX__) || defined(__APPLE__))
1071-
dispatch_release(windowSem);
1072-
#else
1073-
sem_destroy(&windowSem);
1074-
#endif
1104+
wolfSSH_SEMAPHORE_Release(&windowSem);
10751105
#endif /* WOLFSSH_TERM */
10761106
#elif defined(_MSC_VER)
10771107
thread_args arg;

0 commit comments

Comments
 (0)