X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fpbd%2Fbase_ui.cc;h=f22d83264ef08b1c5d4519bd06f16d3ea79c1e71;hb=659701c59b76bdcbfcf5c1b8ce8962eb3f6a1ca2;hp=5e856d1ca082bff15ee4491005e067cf691af44e;hpb=f450df300c9c057141a4caf79ff6dbfbf58492d9;p=ardour.git diff --git a/libs/pbd/base_ui.cc b/libs/pbd/base_ui.cc index 5e856d1ca0..f22d83264e 100644 --- a/libs/pbd/base_ui.cc +++ b/libs/pbd/base_ui.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2007 Paul Davis + Copyright (C) 2000-2007 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,33 +19,42 @@ #include #include +#ifdef COMPILER_MSVC +#include // Microsoft's nearest equivalent to +#else #include +#endif #include #include #include #include "pbd/base_ui.h" +#include "pbd/debug.h" +#include "pbd/pthread_utils.h" #include "pbd/error.h" #include "pbd/compose.h" #include "pbd/failed_constructor.h" -#include "i18n.h" +#include "pbd/i18n.h" + +#include "pbd/debug.h" using namespace std; using namespace PBD; using namespace Glib; - + uint64_t BaseUI::rt_bit = 1; BaseUI::RequestType BaseUI::CallSlot = BaseUI::new_request_type(); BaseUI::RequestType BaseUI::Quit = BaseUI::new_request_type(); -BaseUI::BaseUI (const string& str) - : run_loop_thread (0) - , _name (str) +BaseUI::BaseUI (const string& loop_name) + : EventLoop (loop_name) + , m_context(MainContext::get_default()) + , run_loop_thread (0) + , request_channel (true) { base_ui_instance = this; - - request_channel.ios()->connect (sigc::mem_fun (*this, &BaseUI::request_handler)); + request_channel.set_receive_handler (sigc::mem_fun (*this, &BaseUI::request_handler)); /* derived class must set _ok */ } @@ -70,30 +79,41 @@ BaseUI::new_request_type () void BaseUI::main_thread () { + DEBUG_TRACE (DEBUG::EventLoop, string_compose ("%1: event loop running in thread %2\n", event_loop_name(), pthread_name())); set_event_loop_for_thread (this); thread_init (); + _main_loop->get_context()->signal_idle().connect (sigc::mem_fun (*this, &BaseUI::signal_running)); _main_loop->run (); } +bool +BaseUI::signal_running () +{ + Glib::Threads::Mutex::Lock lm (_run_lock); + _running.signal (); + + return false; // don't call it again +} + void BaseUI::run () { /* to be called by UI's that need/want their own distinct, self-created event loop thread. */ - _main_loop = MainLoop::create (MainContext::create()); - request_channel.ios()->attach (_main_loop->get_context()); - - /* glibmm hack - drop the refptr to the IOSource now before it can hurt */ - request_channel.drop_ios (); + m_context = MainContext::create(); + _main_loop = MainLoop::create (m_context); + attach_request_source (); - run_loop_thread = Thread::create (mem_fun (*this, &BaseUI::main_thread), true); + Glib::Threads::Mutex::Lock lm (_run_lock); + run_loop_thread = Glib::Threads::Thread::create (mem_fun (*this, &BaseUI::main_thread)); + _running.wait (_run_lock); } void BaseUI::quit () { - if (_main_loop->is_running()) { + if (_main_loop && _main_loop->is_running()) { _main_loop->quit (); run_loop_thread->join (); } @@ -102,7 +122,7 @@ BaseUI::quit () bool BaseUI::request_handler (Glib::IOCondition ioc) { - /* check the transport request pipe */ + /* check the request pipe */ if (ioc & ~IO_IN) { _main_loop->quit (); @@ -110,16 +130,33 @@ BaseUI::request_handler (Glib::IOCondition ioc) if (ioc & IO_IN) { request_channel.drain (); - + /* there may been an error. we'd rather handle requests first, and then get IO_HUP or IO_ERR on the next loop. */ /* handle requests */ + DEBUG_TRACE (DEBUG::EventLoop, string_compose ("%1: request handler\n", event_loop_name())); handle_ui_requests (); } return true; } - + +void +BaseUI::signal_new_request () +{ + DEBUG_TRACE (DEBUG::EventLoop, string_compose ("%1: signal_new_request\n", event_loop_name())); + request_channel.wakeup (); +} + +/** + * This method relies on the caller having already set m_context + */ +void +BaseUI::attach_request_source () +{ + DEBUG_TRACE (DEBUG::EventLoop, string_compose ("%1: attach request source\n", event_loop_name())); + request_channel.attach (m_context); +}