diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2009-12-09 03:05:14 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2009-12-09 03:05:14 +0000 |
commit | c38e02285fda1fd7966c9e4ad85994445247e6a6 (patch) | |
tree | a5f46d4350b8df3e0a74558169c696cbb837ce7f /libs/pbd/base_ui.cc | |
parent | 90f95df20707995e267bd624b28980cfd9200bed (diff) |
major design changes: use glib event loop for MIDI thread/UI; rework design of BaseUI and AbstractUI; solo & mute are both temporarily broken; OSC control up next; may segfault during exit
git-svn-id: svn://localhost/ardour2/branches/3.0@6328 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/pbd/base_ui.cc')
-rw-r--r-- | libs/pbd/base_ui.cc | 85 |
1 files changed, 47 insertions, 38 deletions
diff --git a/libs/pbd/base_ui.cc b/libs/pbd/base_ui.cc index 015951f118..259a51d954 100644 --- a/libs/pbd/base_ui.cc +++ b/libs/pbd/base_ui.cc @@ -33,36 +33,24 @@ using namespace std; using namespace PBD; +using namespace Glib; -uint32_t BaseUI::rt_bit = 1; +uint64_t BaseUI::rt_bit = 1; BaseUI::RequestType BaseUI::CallSlot = BaseUI::new_request_type(); -BaseUI::BaseUI (string str, bool with_signal_pipe) - : _name (str) +BaseUI::BaseUI (const string& str) + : run_loop_thread (0) + , _name (str) { - /* odd pseudo-singleton semantics */ - base_ui_instance = this; - signal_pipe[0] = -1; - signal_pipe[1] = -1; + request_channel.ios()->connect (sigc::mem_fun (*this, &BaseUI::request_handler)); - if (with_signal_pipe) { - if (setup_signal_pipe ()) { - throw failed_constructor (); - } - } + /* derived class must set _ok */ } BaseUI::~BaseUI() { - if (signal_pipe[0] >= 0) { - close (signal_pipe[0]); - } - - if (signal_pipe[1] >= 0) { - close (signal_pipe[1]); - } } BaseUI::RequestType @@ -78,32 +66,53 @@ BaseUI::new_request_type () return rt; } -int -BaseUI::setup_signal_pipe () +void +BaseUI::main_thread () +{ + thread_init (); + _main_loop->run (); +} + +void +BaseUI::run () { - /* setup the pipe that other threads send us notifications/requests - through. + /* to be called by UI's that need/want their own distinct, self-created event loop thread. + Derived classes should have set up a handler for IO on request_channel.ios() */ - if (pipe (signal_pipe)) { - error << string_compose (_("%1-UI: cannot create error signal pipe (%2)"), _name, ::strerror (errno)) - << endmsg; + _main_loop = MainLoop::create (MainContext::create()); + request_channel.ios()->attach (_main_loop->get_context()); + run_loop_thread = Thread::create (mem_fun (*this, &BaseUI::main_thread), true); +} - return -1; - } +void +BaseUI::quit () +{ + _main_loop->quit (); + run_loop_thread->join (); +} + +bool +BaseUI::request_handler (Glib::IOCondition ioc) +{ + /* check the transport request pipe */ - if (fcntl (signal_pipe[0], F_SETFL, O_NONBLOCK)) { - error << string_compose (_("%1-UI: cannot set O_NONBLOCK on signal read pipe (%2)"), _name, ::strerror (errno)) - << endmsg; - return -1; + if (ioc & ~IO_IN) { + _main_loop->quit (); } - if (fcntl (signal_pipe[1], F_SETFL, O_NONBLOCK)) { - error << string_compose (_("%1-UI: cannot set O_NONBLOCK on signal write pipe (%2)"), _name, ::strerror (errno)) - << endmsg; - return -1; + 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 */ + + handle_ui_requests (); } - return 0; + return true; } - + |