Make a try at MACOS unnamed semaphores
authorBill Lash <william.lash@gmail.com>
Tue, 25 Jun 2019 02:31:56 +0000 (21:31 -0500)
committerDavid Griffith <dave@661.org>
Sat, 29 Jun 2019 00:37:07 +0000 (17:37 -0700)
Makefile
src/curses/ux_audio.c
src/curses/ux_input.c
src/curses/ux_sema.h [new file with mode: 0644]

index 436a1b7cd03bc1c6b8260fe850a6048ebe6cadd0..8c4de6a2514eb9a26ee094fe24a7a54f58f92e47 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -82,7 +82,7 @@ CURSES ?= ncursesw
 # you need to define _XOPEN_SOURCE_EXTENDED
 ifdef MACOS
   CURSES = curses
-  CFLAGS += -D_XOPEN_SOURCE_EXTENDED
+  CFLAGS += -D_XOPEN_SOURCE_EXTENDED -DMACOS
 endif
 
 # Uncomment this if you want to disable the compilation of Blorb support.
index 95640a35bd9caf9344a366e323cd67b8e44bc6f3..27393871bb362b9af87ed6dba07e93fd669de820 100644 (file)
@@ -29,7 +29,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <pthread.h>
-#include <semaphore.h>
 #include <assert.h>
 #include <unistd.h> //pread
 
 #include <curses.h>
 #endif
 
+#include "ux_sema.h"
 #include "ux_frotz.h"
 #include "ux_audio.h"
 
 f_setup_t f_setup;
-sem_t sound_done;      /* 1 if the sound is done */
+ux_sem_t sound_done;   /* 1 if the sound is done */
 
 #ifndef NO_SOUND
 
@@ -176,8 +176,8 @@ typedef struct {
     sound_state_t   voices[NUM_VOICES];  /* Max concurrent sound effects/music*/
 
     /*Event (one is process per frame of audio)*/
-    sem_t ev_free;    /*1 if an event can be submitted*/
-    sem_t ev_pending; /*1 if there's an event ready to be processed*/
+    ux_sem_t ev_free;    /*1 if an event can be submitted*/
+    ux_sem_t ev_pending; /*1 if there's an event ready to be processed*/
     sound_event_t event;
 } sound_engine_t;
 
@@ -576,12 +576,12 @@ process_engine(sound_engine_t *e)
 {
     int i;
     /*Handle event*/
-    if(sem_trywait(&e->ev_pending) == 0) {
+    if(ux_sem_trywait(&e->ev_pending) == 0) {
         if(e->event.type == EVENT_START_STREAM)
             sound_enqueue_real(e,e->event.e);
         else if(e->event.type == EVENT_STOP_STREAM)
             sound_stop_id_real(e,e->event.i);
-        sem_post(&e->ev_free);
+        ux_sem_post(&e->ev_free);
     }
 
     /*Start out with an empty buffer*/
@@ -605,7 +605,7 @@ process_engine(sound_engine_t *e)
                 sound->cleanup(sound);
                 free(sound);
                 e->streams[i] = NULL;
-                sem_post(&sound_done);
+                ux_sem_post(&sound_done);
             }
         }
     }
@@ -696,10 +696,10 @@ static sound_stream_t *load_aiff(FILE *fp, long startpos, long length, int id, f
 static void
 sound_stop_id(int id)
 {
-    sem_wait(&frotz_audio.ev_free);
+    ux_sem_wait(&frotz_audio.ev_free);
     frotz_audio.event.type = EVENT_STOP_STREAM;
     frotz_audio.event.i    = id;
-    sem_post(&frotz_audio.ev_pending);
+    ux_sem_post(&frotz_audio.ev_pending);
 }
 
 static void
@@ -720,10 +720,10 @@ sound_stop_id_real(sound_engine_t *e, int id)
 static void
 sound_enqueue(sound_stream_t *s)
 {
-    sem_wait(&frotz_audio.ev_free);
+    ux_sem_wait(&frotz_audio.ev_free);
     frotz_audio.event.type = EVENT_START_STREAM;
     frotz_audio.event.e    = s;
-    sem_post(&frotz_audio.ev_pending);
+    ux_sem_post(&frotz_audio.ev_pending);
 }
 
 static void
@@ -794,9 +794,9 @@ os_init_sound(void)
         frotz_audio.voices[i].active = 0;
 
     /*No events registered on startup*/
-    sem_init(&frotz_audio.ev_free,    0, 1);
-    sem_init(&frotz_audio.ev_pending, 0, 0);
-    sem_init(&sound_done, 0, 0);
+    ux_sem_init(&frotz_audio.ev_free,    0, 1);
+    ux_sem_init(&frotz_audio.ev_pending, 0, 0);
+    ux_sem_init(&sound_done, 0, 0);
     frotz_audio.event.type = 0;
 
     /*Start audio thread*/
index ba0262fddb7c29d6aba4eb907286e8368aa1b557..45d7e6b64e7a49ed020befa1bd2e117c691a59b0 100644 (file)
@@ -40,8 +40,8 @@
 #endif
 
 #ifndef NO_SOUND
-#include <semaphore.h>
-sem_t sound_done;
+#include "ux_sema.h"
+ux_sem_t sound_done;
 #endif
 
 #include "ux_frotz.h"
@@ -152,7 +152,7 @@ void os_tick()
     }
 
 #ifndef NO_SOUND
-    if (sem_trywait(&sound_done) == 0)
+    if (ux_sem_trywait(&sound_done) == 0)
        end_of_sound();
 #endif
 }
diff --git a/src/curses/ux_sema.h b/src/curses/ux_sema.h
new file mode 100644 (file)
index 0000000..7a01cd4
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * ux_sema.h - semaphore abstraction for frotz
+ *
+ * This file is part of Frotz.
+ *
+ * Frotz is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Frotz is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * Or visit http://www.fsf.org/
+ *
+ * This file and only this file is dual licensed under the MIT license.
+ *
+ */
+
+/*
+ * For anything other than MAC OS X, this is a simple wrapper for unnamed
+ * POSIX Semaphores.  For MAC OS X use the Grand Central Dispatch as suggested
+ * at https://stackoverflow.com/questions/27736618/why-are-sem-init-sem-getvalue-sem-destroy-deprecated-on-mac-os-x-and-w 
+ */
+
+#ifdef MACOS
+#include <dispatch/dispatch.h>
+struct ux_sema {
+    dispatch_semaphore_t dsem;
+};
+typedef struct ux_sema ux_sem_t;
+
+/* 
+ * Note that the current implementation does not check return codes
+ * so use void to make things simpler on the MAC side
+ */
+static inline void  ux_sem_init(ux_sem_t *sem, int pshared, unsigned int value)
+{
+    dispatch_semaphore_t *sema = &sem->dsem;
+    (void) pshared;
+
+    *sema = dispatch_semaphore_create(value);
+}
+
+static inline void  ux_sem_post(ux_sem_t *sem)
+{
+    dispatch_semaphore_signal(sem->dsem);
+}
+
+static inline void ux_sem_wait(ux_sem_t *sem)
+{
+    dispatch_semaphore_wait(sem->dsem, DISPATCH_TIME_FOREVER);
+}
+
+static inline int ux_sem_trywait(ux_sem_t *sem)
+{
+    return (int) dispatch_semaphore_wait(sem->dsem, DISPATCH_TIME_NOW);
+}
+#else
+#include <semaphore.h>
+typedef sem_t ux_sem_t;
+
+/* 
+ * Note that the current implementation does not check return codes
+ * so use void to make things simpler on the MAC side
+ */
+static inline void  ux_sem_init(ux_sem_t *sem, int pshared, unsigned int value)
+{
+    (void) sem_init(sem, pshared, value);
+}
+
+static inline void  ux_sem_post(ux_sem_t *sem)
+{
+    (void) sem_post(sem);
+}
+
+static inline void ux_sem_wait(ux_sem_t *sem)
+{
+    (void) sem_wait(sem);
+}
+
+static inline int ux_sem_trywait(ux_sem_t *sem)
+{
+    return sem_trywait(sem);
+}
+#endif