> on various Mac OS X, the gnulib test 'test-lock' fails with exit code 134 > (SIGABRT?)
Fixed as follows: 2017-03-03 Bruno Haible <br...@clisp.org> lock tests: Fix test failure on Mac OS X (regression from 2017-01-05). Reported by Assaf Gordon <assafgor...@gmail.com> via Pádraig Brady <p...@draigbrady.com>. * tests/test-lock.c: On Mac OS X, use named semaphores, not unnamed semaphores. (USE_NAMED_SEMAPHORE, USE_UNNAMED_SEMAPHORE): New macros. (atomic_int_semaphore): New macro. diff --git a/tests/test-lock.c b/tests/test-lock.c index c6bc399..fb18dee 100644 --- a/tests/test-lock.c +++ b/tests/test-lock.c @@ -63,6 +63,13 @@ If set to 0, a lock is used. If set to 1, a semaphore is used. Uncomment this to reduce the dependencies of this test. */ # define USE_SEMAPHORE 1 +/* Mac OS X provides only named semaphores (sem_open); its facility for + unnamed semaphores (sem_init) does not work. */ +# if defined __APPLE__ && defined __MACH__ +# define USE_NAMED_SEMAPHORE 1 +# else +# define USE_UNNAMED_SEMAPHORE 1 +# endif #endif /* Whether to print debugging messages. */ @@ -107,7 +114,9 @@ #include "glthread/yield.h" #if USE_SEMAPHORE # include <errno.h> +# include <fcntl.h> # include <semaphore.h> +# include <unistd.h> #endif #if ENABLE_DEBUGGING @@ -143,20 +152,66 @@ set_atomic_int_value (struct atomic_int *ai, int new_value) #elif USE_SEMAPHORE /* This atomic_int implementation can only support the values 0 and 1. It is initially 0 and can be set to 1 only once. */ +# if USE_UNNAMED_SEMAPHORE struct atomic_int { sem_t semaphore; }; +#define atomic_int_semaphore(ai) (&(ai)->semaphore) static void init_atomic_int (struct atomic_int *ai) { sem_init (&ai->semaphore, 0, 0); } +# endif +# if USE_NAMED_SEMAPHORE +struct atomic_int { + sem_t *semaphore; +}; +#define atomic_int_semaphore(ai) ((ai)->semaphore) +static void +init_atomic_int (struct atomic_int *ai) +{ + sem_t *s; + unsigned int count; + for (count = 0; ; count++) + { + char name[80]; + /* Use getpid() in the name, so that different processes running at the + same time will not interfere. Use ai in the name, so that different + atomic_int in the same process will not interfere. Use a count in + the name, so that even in the (unlikely) case that a semaphore with + the specified name already exists, we can try a different name. */ + sprintf (name, "test-lock-%lu-%p-%u", + (unsigned long) getpid (), ai, count); + s = sem_open (name, O_CREAT | O_EXCL, 0600, 0); + if (s == SEM_FAILED) + { + if (errno == EEXIST) + /* Retry with a different name. */ + continue; + else + { + perror ("sem_open failed"); + abort (); + } + } + else + { + /* Try not to leave a semaphore hanging around on the file system + eternally, if we can avoid it. */ + sem_unlink (name); + break; + } + } + ai->semaphore = s; +} +# endif static int get_atomic_int_value (struct atomic_int *ai) { - if (sem_trywait (&ai->semaphore) == 0) + if (sem_trywait (atomic_int_semaphore (ai)) == 0) { - if (sem_post (&ai->semaphore)) + if (sem_post (atomic_int_semaphore (ai))) abort (); return 1; } @@ -172,7 +227,7 @@ set_atomic_int_value (struct atomic_int *ai, int new_value) /* It's already initialized with 0. */ return; /* To set the value 1: */ - if (sem_post (&ai->semaphore)) + if (sem_post (atomic_int_semaphore (ai))) abort (); } #else