[beast: 3/4] BSE: reap master thread atexit



commit 90867e9675f33ed493f043700834759f2934d873
Author: Tim Janik <timj gnu org>
Date:   Tue Sep 8 12:05:25 2015 +0200

    BSE: reap master thread atexit

 bse/bseengine.cc       |   15 ++-------------
 bse/bseenginemaster.cc |   42 +++++++++++++++++++++++++++++++++++++++---
 bse/bseenginemaster.hh |    8 +++++---
 3 files changed, 46 insertions(+), 19 deletions(-)
---
diff --git a/bse/bseengine.cc b/bse/bseengine.cc
index 9a32370..e237002 100644
--- a/bse/bseengine.cc
+++ b/bse/bseengine.cc
@@ -20,9 +20,6 @@
 #define ERESTART        EINTR
 #endif
 
-/* --- prototypes --- */
-static void wakeup_master (void);
-
 /* --- UserThread --- */
 /**
  * @param klass        the BseModuleClass which determines the module's behaviour
@@ -975,7 +972,7 @@ bse_trans_commit (BseTrans *trans)
     {
       trans->comitted = TRUE;
       exec_tick_stamp = _engine_enqueue_trans (trans);
-      wakeup_master ();
+      Bse::MasterThread::wakeup();
     }
   else
     bse_trans_dismiss (trans);
@@ -1199,7 +1196,6 @@ slave (gpointer data)
 /* --- setup & trigger --- */
 static gboolean                bse_engine_initialized = FALSE;
 static gboolean                bse_engine_threaded = FALSE;
-static Bse::MasterThread *master_thread = NULL;
 guint                  bse_engine_exvar_block_size = 0;
 guint                  bse_engine_exvar_sample_freq = 0;
 guint                  bse_engine_exvar_control_mask = 0;
@@ -1382,18 +1378,11 @@ bse_engine_init (gboolean run_threaded)
   bse_engine_threaded = run_threaded;
   if (bse_engine_threaded)
     {
-      master_thread = new Bse::MasterThread (bse_main_wakeup);
+      Bse::MasterThread::start (bse_main_wakeup);
       (void) slave; // FIXME: start slave ("DSP #2")
     }
 }
 
-static void
-wakeup_master (void)
-{
-  g_return_if_fail (master_thread != NULL);
-  master_thread->wakeup();
-}
-
 gboolean
 bse_engine_prepare (BseEngineLoop *loop)
 {
diff --git a/bse/bseenginemaster.cc b/bse/bseenginemaster.cc
index 84bad2b..d18f9be 100644
--- a/bse/bseenginemaster.cc
+++ b/bse/bseenginemaster.cc
@@ -1123,10 +1123,11 @@ MasterThread::MasterThread (const std::function<void()> &caller_wakeup) :
 {
   assert (caller_wakeup_ != NULL);
   if (event_fd_.open() != 0)
-    g_error ("failed to create engine wake-up pipe: %s", strerror (errno));
-  thread_ = std::thread (&MasterThread::master_thread, this); // FIXME: join on exit
+    fatal ("BSE: failed to create master thread wake-up pipe: %s", strerror (errno));
 }
 
+static std::atomic<bool> master_thread_running { false };
+
 void
 MasterThread::master_thread()
 {
@@ -1149,7 +1150,7 @@ MasterThread::master_thread()
   master_n_pollfds = 1;
   master_pollfds_changed = TRUE;
   toyprof_stampinit ();
-  while (1)
+  while (master_thread_running)
     {
       BseEngineLoop loop;
       bool need_dispatch;
@@ -1176,4 +1177,39 @@ MasterThread::master_thread()
   Bse::TaskRegistry::remove (Rapicorn::ThisThread::thread_pid());
 }
 
+static std::atomic<MasterThread*> master_thread_singleton { NULL };
+
+void
+MasterThread::reap_master_thread ()
+{
+  assert (master_thread_singleton != NULL);
+  assert_return (master_thread_running == true);
+  master_thread_running = false;
+  MasterThread::wakeup();
+  MasterThread *mthread = master_thread_singleton;
+  mthread->thread_.join();
+  master_thread_singleton = NULL;
+  delete mthread;
+}
+
+void
+MasterThread::start (const std::function<void()> &caller_wakeup)
+{
+  assert (master_thread_singleton == NULL);
+  MasterThread *mthread = new MasterThread (caller_wakeup);
+  master_thread_singleton = mthread;
+  assert (master_thread_running == false);
+  if (std::atexit (reap_master_thread) != 0)
+    fatal ("BSE: failed to install master thread reaper");
+  master_thread_running = true;
+  mthread->thread_ = std::thread (&MasterThread::master_thread, mthread);
+}
+
+void
+MasterThread::wakeup ()
+{
+  assert_return (master_thread_singleton != NULL);
+  master_thread_singleton.load()->event_fd_.wakeup();
+}
+
 } // Bse
diff --git a/bse/bseenginemaster.hh b/bse/bseenginemaster.hh
index 4bc8fcb..d6ce2ae 100644
--- a/bse/bseenginemaster.hh
+++ b/bse/bseenginemaster.hh
@@ -16,10 +16,12 @@ class MasterThread {
   std::thread           thread_;
   EventFd               event_fd_;
   std::function<void()> caller_wakeup_;
-  void          master_thread   ();
+  static void reap_master_thread ();
+  void        master_thread      ();
+  explicit    MasterThread       (const std::function<void()> &caller_wakeup);
 public:
-  explicit      MasterThread    (const std::function<void()> &caller_wakeup);
-  void          wakeup          ()      { event_fd_.wakeup(); }
+  static void wakeup             ();
+  static void start              (const std::function<void()> &caller_wakeup);
 };
 
 } // Bse


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