Skip to content

Commit 2f1231d

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 ce28fc0 commit 2f1231d

2 files changed

Lines changed: 136 additions & 62 deletions

File tree

apps/wolfssh/wolfssh.c

Lines changed: 68 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -272,22 +272,70 @@ 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+
if (s != NULL) {
290+
snprintf(s->name, sizeof(s->name), "/wolfssh_winch_%d", (int)getpid());
291+
s->s = sem_open(s->name, O_CREAT | O_EXCL | O_RDWR, 0600, n);
292+
if (s->s == SEM_FAILED && errno == EEXIST) {
293+
/* named semaphore already exists, unlink the name and
294+
* try to open it one more time. */
295+
if (sem_unlink(s->name) == 0) {
296+
s->s = sem_open(s->name, O_CREAT | O_RDWR, 0600, n);
297+
}
298+
}
299+
}
300+
return (s != NULL && s->s != SEM_FAILED);
301+
}
302+
303+
static inline
304+
void wolfSSH_SEMAPHORE_Release(WOLFSSH_SEMAPHORE* s)
305+
{
306+
if (s != NULL && s->s != NULL && s->s != SEM_FAILED) {
307+
sem_close(s->s);
308+
sem_unlink(s->name);
309+
s->s = NULL;
310+
}
311+
}
312+
313+
static inline
314+
int wolfSSH_SEMAPHORE_Wait(WOLFSSH_SEMAPHORE* s)
315+
{
316+
int ret = -1;
317+
if (s != NULL && s->s != NULL && s->s != SEM_FAILED) {
318+
do {
319+
ret = sem_wait(s->s);
320+
} while (ret == -1 && errno == EINTR);
321+
}
322+
return (ret == 0);
323+
}
324+
325+
static inline
326+
void wolfSSH_SEMAPHORE_Post(WOLFSSH_SEMAPHORE* s)
327+
{
328+
if (s != NULL && s->s != NULL && s->s != SEM_FAILED) {
329+
sem_post(s->s);
330+
}
331+
}
332+
333+
static WOLFSSH_SEMAPHORE windowSem;
282334

283335
/* capture window change signals */
284336
static void WindowChangeSignal(int sig)
285337
{
286-
#if (defined(__OSX__) || defined(__APPLE__))
287-
dispatch_semaphore_signal(windowSem);
288-
#else
289-
sem_post(&windowSem);
290-
#endif
338+
wolfSSH_SEMAPHORE_Post(&windowSem);
291339
(void)sig;
292340
}
293341

@@ -299,11 +347,9 @@ static THREAD_RET windowMonitor(void* in)
299347

300348
args = (thread_args*)in;
301349
do {
302-
#if (defined(__OSX__) || defined(__APPLE__))
303-
dispatch_semaphore_wait(windowSem, DISPATCH_TIME_FOREVER);
304-
#else
305-
sem_wait(&windowSem);
306-
#endif
350+
if (!wolfSSH_SEMAPHORE_Wait(&windowSem)) {
351+
break;
352+
}
307353
if (args->quit) {
308354
break;
309355
}
@@ -1060,11 +1106,9 @@ static THREAD_RETURN WOLFSSH_THREAD wolfSSH_Client(void* args)
10601106
arg.readError = 0;
10611107
#ifdef WOLFSSH_TERM
10621108
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
1109+
if (!wolfSSH_SEMAPHORE_Init(&windowSem, 0)) {
1110+
err_sys("Couldn't initialize window semaphore.");
1111+
}
10681112

10691113
if (config.command) {
10701114
int err;
@@ -1087,21 +1131,14 @@ static THREAD_RETURN WOLFSSH_THREAD wolfSSH_Client(void* args)
10871131
#ifdef WOLFSSH_TERM
10881132
/* Wake the windowMonitor thread so it can exit. */
10891133
arg.quit = 1;
1090-
#if (defined(__OSX__) || defined(__APPLE__))
1091-
dispatch_semaphore_signal(windowSem);
1092-
#else
1093-
sem_post(&windowSem);
1094-
#endif
1134+
signal(SIGWINCH, SIG_DFL);
1135+
wolfSSH_SEMAPHORE_Post(&windowSem);
10951136
pthread_join(thread[0], NULL);
10961137
#endif /* WOLFSSH_TERM */
10971138
pthread_cancel(thread[1]);
10981139
pthread_join(thread[1], NULL);
10991140
#ifdef WOLFSSH_TERM
1100-
#if (defined(__OSX__) || defined(__APPLE__))
1101-
dispatch_release(windowSem);
1102-
#else
1103-
sem_destroy(&windowSem);
1104-
#endif
1141+
wolfSSH_SEMAPHORE_Release(&windowSem);
11051142
#endif /* WOLFSSH_TERM */
11061143
ioErr = arg.readError;
11071144
#elif defined(_MSC_VER)

examples/client/client.c

Lines changed: 68 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -240,22 +240,70 @@ 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+
if (s != NULL) {
258+
snprintf(s->name, sizeof(s->name), "/wolfssh_winch_%d", (int)getpid());
259+
s->s = sem_open(s->name, O_CREAT | O_EXCL | O_RDWR, 0600, n);
260+
if (s->s == SEM_FAILED && errno == EEXIST) {
261+
/* named semaphore already exists, unlink the name and
262+
* try to open it one more time. */
263+
if (sem_unlink(s->name) == 0) {
264+
s->s = sem_open(s->name, O_CREAT | O_RDWR, 0600, n);
265+
}
266+
}
267+
}
268+
return (s != NULL && s->s != SEM_FAILED);
269+
}
270+
271+
static inline
272+
void wolfSSH_SEMAPHORE_Release(WOLFSSH_SEMAPHORE* s)
273+
{
274+
if (s != NULL && s->s != NULL && s->s != SEM_FAILED) {
275+
sem_close(s->s);
276+
sem_unlink(s->name);
277+
s->s = NULL;
278+
}
279+
}
280+
281+
static inline
282+
int wolfSSH_SEMAPHORE_Wait(WOLFSSH_SEMAPHORE* s)
283+
{
284+
int ret = -1;
285+
if (s != NULL && s->s != NULL && s->s != SEM_FAILED) {
286+
do {
287+
ret = sem_wait(s->s);
288+
} while (ret == -1 && errno == EINTR);
289+
}
290+
return (ret == 0);
291+
}
292+
293+
static inline
294+
void wolfSSH_SEMAPHORE_Post(WOLFSSH_SEMAPHORE* s)
295+
{
296+
if (s != NULL && s->s != NULL && s->s != SEM_FAILED) {
297+
sem_post(s->s);
298+
}
299+
}
300+
301+
static WOLFSSH_SEMAPHORE windowSem;
250302

251303
/* capture window change signals */
252304
static void WindowChangeSignal(int sig)
253305
{
254-
#if (defined(__OSX__) || defined(__APPLE__))
255-
dispatch_semaphore_signal(windowSem);
256-
#else
257-
sem_post(&windowSem);
258-
#endif
306+
wolfSSH_SEMAPHORE_Post(&windowSem);
259307
(void)sig;
260308
}
261309

@@ -267,11 +315,9 @@ static THREAD_RET windowMonitor(void* in)
267315

268316
args = (thread_args*)in;
269317
do {
270-
#if (defined(__OSX__) || defined(__APPLE__))
271-
dispatch_semaphore_wait(windowSem, DISPATCH_TIME_FOREVER);
272-
#else
273-
sem_wait(&windowSem);
274-
#endif
318+
if (!wolfSSH_SEMAPHORE_Wait(&windowSem)) {
319+
break;
320+
}
275321
if (args->quit) {
276322
break;
277323
}
@@ -1032,11 +1078,9 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
10321078
arg.quit = 0;
10331079
wc_InitMutex(&arg.lock);
10341080
#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
1081+
if (!wolfSSH_SEMAPHORE_Init(&windowSem, 0)) {
1082+
err_sys("Couldn't initialize window semaphore.");
1083+
}
10401084

10411085
if (cmd) {
10421086
int err;
@@ -1057,21 +1101,14 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
10571101
#ifdef WOLFSSH_TERM
10581102
/* Wake the windowMonitor thread so it can exit. */
10591103
arg.quit = 1;
1060-
#if (defined(__OSX__) || defined(__APPLE__))
1061-
dispatch_semaphore_signal(windowSem);
1062-
#else
1063-
sem_post(&windowSem);
1064-
#endif
1104+
signal(SIGWINCH, SIG_DFL);
1105+
wolfSSH_SEMAPHORE_Post(&windowSem);
10651106
pthread_join(thread[0], NULL);
10661107
#endif /* WOLFSSH_TERM */
10671108
pthread_cancel(thread[1]);
10681109
pthread_join(thread[1], NULL);
10691110
#ifdef WOLFSSH_TERM
1070-
#if (defined(__OSX__) || defined(__APPLE__))
1071-
dispatch_release(windowSem);
1072-
#else
1073-
sem_destroy(&windowSem);
1074-
#endif
1111+
wolfSSH_SEMAPHORE_Release(&windowSem);
10751112
#endif /* WOLFSSH_TERM */
10761113
#elif defined(_MSC_VER)
10771114
thread_args arg;

0 commit comments

Comments
 (0)