2 Copyright (C) 2000-2007 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include <io.h> // Microsoft's nearest equivalent to <unistd.h>
34 #include "pbd/base_ui.h"
35 #include "pbd/debug.h"
36 #include "pbd/pthread_utils.h"
37 #include "pbd/error.h"
38 #include "pbd/compose.h"
39 #include "pbd/failed_constructor.h"
43 #include "pbd/debug.h"
49 uint64_t BaseUI::rt_bit = 1;
50 BaseUI::RequestType BaseUI::CallSlot = BaseUI::new_request_type();
51 BaseUI::RequestType BaseUI::Quit = BaseUI::new_request_type();
53 BaseUI::BaseUI (const string& loop_name)
54 : EventLoop (loop_name)
55 , m_context(MainContext::get_default())
57 , request_channel (true)
59 base_ui_instance = this;
60 request_channel.set_receive_handler (sigc::mem_fun (*this, &BaseUI::request_handler));
62 /* derived class must set _ok */
70 BaseUI::new_request_type ()
74 /* XXX catch out-of-range */
76 rt = RequestType (rt_bit);
83 BaseUI::set_thread_priority (const int policy, int priority) const
85 return pbd_set_thread_priority (pthread_self(), policy, priority);
89 BaseUI::main_thread ()
91 DEBUG_TRACE (DEBUG::EventLoop, string_compose ("%1: event loop running in thread %2\n", event_loop_name(), pthread_name()));
92 set_event_loop_for_thread (this);
94 _main_loop->get_context()->signal_idle().connect (sigc::mem_fun (*this, &BaseUI::signal_running));
99 BaseUI::signal_running ()
101 Glib::Threads::Mutex::Lock lm (_run_lock);
104 return false; // don't call it again
110 /* to be called by UI's that need/want their own distinct, self-created event loop thread.
113 m_context = MainContext::create();
114 _main_loop = MainLoop::create (m_context);
115 attach_request_source ();
117 Glib::Threads::Mutex::Lock lm (_run_lock);
118 run_loop_thread = Glib::Threads::Thread::create (mem_fun (*this, &BaseUI::main_thread));
119 _running.wait (_run_lock);
125 if (_main_loop && _main_loop->is_running()) {
127 run_loop_thread->join ();
132 BaseUI::request_handler (Glib::IOCondition ioc)
134 /* check the request pipe */
141 request_channel.drain ();
143 /* there may been an error. we'd rather handle requests first,
144 and then get IO_HUP or IO_ERR on the next loop.
147 /* handle requests */
149 DEBUG_TRACE (DEBUG::EventLoop, string_compose ("%1: request handler\n", event_loop_name()));
150 handle_ui_requests ();
157 BaseUI::signal_new_request ()
159 DEBUG_TRACE (DEBUG::EventLoop, string_compose ("%1: signal_new_request\n", event_loop_name()));
160 request_channel.wakeup ();
164 * This method relies on the caller having already set m_context
167 BaseUI::attach_request_source ()
169 DEBUG_TRACE (DEBUG::EventLoop, string_compose ("%1: attach request source\n", event_loop_name()));
170 request_channel.attach (m_context);