[beast: 3/4] BSE: reap master thread atexit
- From: Tim Janik <timj src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [beast: 3/4] BSE: reap master thread atexit
- Date: Sun, 13 Sep 2015 09:06:44 +0000 (UTC)
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]