]> Savannah Git Hosting - gnulib.git/commitdiff
lock tests: Fix test failure on Mac OS X (regression from 2017-01-05).
authorBruno Haible <bruno@clisp.org>
Fri, 3 Mar 2017 11:13:48 +0000 (12:13 +0100)
committerBruno Haible <bruno@clisp.org>
Fri, 3 Mar 2017 11:13:48 +0000 (12:13 +0100)
Reported by Assaf Gordon <assafgordon@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.

ChangeLog
tests/test-lock.c

index 1622f4291a52b6c07d263714b6202cca84125d90..99af22aeaf31d963f2b2d1351fc8958bebe9c8a6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2017-03-03  Bruno Haible  <bruno@clisp.org>
+
+       lock tests: Fix test failure on Mac OS X (regression from 2017-01-05).
+       Reported by Assaf Gordon <assafgordon@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.
+
 2017-02-28  Bruno Haible  <bruno@clisp.org>
 
        perror tests: Tweak for z/OS.
index c6bc399f7dec6b451ba572bbe1c17cf5ca98de3c..fb18dee9aa02a55c867118e1203c1e08eed79554 100644 (file)
    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.  */
 #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