[beast/win32] Implemented alternative wakeup mechanism (instead of pipe based wakeup).



commit 5b58d4856a3bbc1617555ac2ea4b5503df6c7881
Author: Stefan Westerfeld <stefan space twc de>
Date:   Sat Sep 5 10:06:24 2009 +0200

    Implemented alternative wakeup mechanism (instead of pipe based wakeup).
    
    Based on 012_seq_waiter_and_domain.diff.

 bse/Makefile.am     |    4 +-
 bse/bsesequencer.cc |   27 ++++++++++++++++---
 bse/bsewin32.cc     |   74 +++++++++++++++++++++++++++++++++++++++++++++++++++
 bse/bsewin32.h      |   35 ++++++++++++++++++++++++
 4 files changed, 134 insertions(+), 6 deletions(-)
---
diff --git a/bse/Makefile.am b/bse/Makefile.am
index 0f14559..fde2524 100644
--- a/bse/Makefile.am
+++ b/bse/Makefile.am
@@ -56,7 +56,7 @@ bse_public_headers = $(strip \
 	bsenote.h		bsemidifile.h		bseblockutils.hh		\
 	bsecxxvalue.hh		bsecxxutils.hh		bsecxxbase.hh			bsecxxclosure.hh \
 	bsecxxarg.hh		bsecxxmodule.hh		bsecxxplugin.hh			bseloader.h \
-	bseresampler.hh		bseresamplerimpl.hh	\
+	bseresampler.hh		bseresamplerimpl.hh	bsewin32.h \
 )
 # BSE C & C++ sources
 bse_sources = $(strip \
@@ -94,7 +94,7 @@ bse_sources = $(strip \
 	bseloader-mad.c		bseloader-wav.c		\
 	bsebusmodule.cc		\
 	bsecore.cc		\
-	bseprobe.cc		\
+	bseprobe.cc		bsewin32.cc		\
 )
 # BSE Synthesis Modules
 bse_idl_sources =
diff --git a/bse/bsesequencer.cc b/bse/bsesequencer.cc
index 680d59f..8a33571 100644
--- a/bse/bsesequencer.cc
+++ b/bse/bsesequencer.cc
@@ -24,7 +24,9 @@
 #include "bsemidireceiver.h"
 #include "bsemain.h"
 #include "bseieee754.h"
-#ifndef WIN32
+#ifdef WIN32
+#include "bsewin32.h"
+#else
 #include <sys/poll.h>
 #endif
 #include <unistd.h>
@@ -55,7 +57,11 @@ static void	bse_sequencer_process_song_SL	(BseSong	*song,
 /* --- variables --- */
 static BseSequencer    *global_sequencer = NULL;
 static BirnetCond          current_watch_cond = { 0, };
+#ifdef WIN32
+static BseWin32Waiter  *sequencer_win32_waiter;
+#else
 static gint             sequencer_wake_up_pipe[2] = { -1, -1 };
+#endif
 
 /* --- functions --- */
 extern "C" void
@@ -65,7 +71,9 @@ bse_sequencer_init_thread (void)
 
   sfi_cond_init (&current_watch_cond);
 
-#ifndef WIN32
+#ifdef WIN32
+  sequencer_win32_waiter = bse_win32_waiter_new();
+#else
   if (pipe (sequencer_wake_up_pipe) < 0)
     g_error ("failed to create sequencer wake-up pipe: %s", strerror (errno));
   glong flags = fcntl (sequencer_wake_up_pipe[0], F_GETFL, 0);
@@ -88,11 +96,15 @@ bse_sequencer_init_thread (void)
 static void
 sequencer_wake_up (gpointer wake_up_data)
 {
+#ifdef WIN32
+  bse_win32_waiter_wakeup (sequencer_win32_waiter);
+#else
   guint8 wake_up_message = 'W';
   gint err;
   do
     err = write (sequencer_wake_up_pipe[1], &wake_up_message, 1);
   while (err < 0 && errno == EINTR);
+#endif
 }
 
 namespace { // Anon
@@ -272,22 +284,30 @@ bse_sequencer_poll_Lm (gint timeout_ms)
 {
   guint n_pfds = sequencer_poll_pool.get_n_pfds() + 1;  /* one for the wake-up pipe */
   GPollFD *pfds = g_newa (GPollFD, n_pfds);
+#ifndef WIN32
   pfds[0].fd = sequencer_wake_up_pipe[0];
+#endif
   pfds[0].events = G_IO_IN;
   pfds[0].revents = 0;
   sequencer_poll_pool.fill_pfds (n_pfds - 1, pfds + 1); /* rest used for io watch array */
   BSE_SEQUENCER_UNLOCK ();
-#ifndef WIN32
+#ifdef WIN32
+  gint result = bse_win32_waiter_wait (sequencer_win32_waiter, timeout_ms);
+  pfds[0].revents = G_IO_IN;
+#else
   gint result = poll ((struct pollfd*) pfds, n_pfds, timeout_ms);
   if (result < 0 && errno != EINTR)
     g_printerr ("%s: poll() error: %s\n", G_STRFUNC, g_strerror (errno));
+#endif
   BSE_SEQUENCER_LOCK ();
+#ifndef WIN32
   if (result > 0 && pfds[0].revents)
     {
       guint8 buffer[256];
       read (sequencer_wake_up_pipe[0], buffer, 256);    /* eat wake up message */
       result -= 1;
     }
+#endif
   if (result > 0)
     {
       /* dispatch io watches */
@@ -310,7 +330,6 @@ bse_sequencer_poll_Lm (gint timeout_ms)
           sfi_cond_broadcast (&current_watch_cond);     /* wake up threads in bse_sequencer_remove_io_watch() */
         }
     }
-#endif
   return !sfi_thread_aborted();
 }
 
diff --git a/bse/bsewin32.cc b/bse/bsewin32.cc
new file mode 100644
index 0000000..dc2269e
--- /dev/null
+++ b/bse/bsewin32.cc
@@ -0,0 +1,74 @@
+/* BSE - Bedevilled Sound Engine
+ * Copyright (C) 2006 Stefan Westerfeld
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+ * The notification stuff was adapted from glib's gmain.c (also LGPL,
+ * see glib's AUTHORS file for individual authors).
+ */
+#include "bsewin32.h"
+#include <windows.h>
+
+struct _BseWin32Waiter
+{
+  HANDLE wake_up_semaphore;
+};
+
+extern "C" BseWin32Waiter *
+bse_win32_waiter_new ()
+{
+  BseWin32Waiter *waiter = g_new0 (BseWin32Waiter, 1);
+
+  waiter->wake_up_semaphore = CreateSemaphore (NULL, 0, 100, NULL);
+  if (waiter->wake_up_semaphore == NULL)
+    g_error ("Cannot create wake-up semaphore: %s",
+             g_win32_error_message (GetLastError ()));
+
+  return waiter;
+}
+
+extern "C" void
+bse_win32_waiter_destroy (BseWin32Waiter *waiter)
+{
+  CloseHandle (waiter->wake_up_semaphore);
+}
+
+extern "C" void
+bse_win32_waiter_wakeup (BseWin32Waiter *waiter)
+{
+  ReleaseSemaphore (waiter->wake_up_semaphore, 1, NULL);
+}
+
+extern "C" int
+bse_win32_waiter_wait (BseWin32Waiter *waiter,
+                       int             timeout)
+{
+  HANDLE handles[1] = { waiter->wake_up_semaphore }; 
+
+  guint ready = WaitForMultipleObjects (1, handles, FALSE, timeout < 0 ? INFINITE : timeout);
+  if (ready == WAIT_FAILED)
+    {
+      gchar *emsg = g_win32_error_message (GetLastError ());
+      g_warning (G_STRLOC ": WaitForMultipleObjects() failed: %s", emsg);
+      g_free (emsg);
+
+      return -1;
+    }
+  if (ready == WAIT_TIMEOUT)
+    return 0;
+  return 1;
+}
diff --git a/bse/bsewin32.h b/bse/bsewin32.h
new file mode 100644
index 0000000..8e90aa5
--- /dev/null
+++ b/bse/bsewin32.h
@@ -0,0 +1,35 @@
+/* BSE - Bedevilled Sound Engine
+ * Copyright (C) 2006 Stefan Westerfeld
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __BSE_WIN32_H__
+#define __BSE_WIN32_H__
+
+#include <bse/bsedefs.h>
+
+G_BEGIN_DECLS
+
+typedef struct _BseWin32Waiter BseWin32Waiter;
+
+BseWin32Waiter *bse_win32_waiter_new ();
+void            bse_win32_waiter_destroy (BseWin32Waiter *waiter);
+void		bse_win32_waiter_wakeup (BseWin32Waiter *waiter);
+int		bse_win32_waiter_wait (BseWin32Waiter *waiter, int timeout);
+
+G_END_DECLS
+
+#endif /* __BSE_BLOCK_UTILS_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]