Skip to content

Commit 5be43b6

Browse files
authored
Merge pull request #895 from ejohnstown/SEM
macOS Semaphore Cleanup
2 parents ce28fc0 + 2f1231d commit 5be43b6

File tree

2 files changed

+136
-62
lines changed

2 files changed

+136
-62
lines changed

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)