sigx++ 2.0.1
|
A useful and convenient thread wrapper for Glib threads. More...
#include <glib_threadable.h>
Public Member Functions | |
glib_threadable () | |
Constructs the threadable object. | |
virtual | ~glib_threadable () |
dtor. | |
template<typename T_functor > | |
void | run (const T_functor &func_on_thread_ready) |
Creates a joinable thread. | |
void | run () |
Creates a joinable thread. | |
void | finish () |
Ends the thread, joins it and frees all its resources. | |
Protected Member Functions | |
Glib::RefPtr< Glib::MainContext > | maincontext () |
access the thread's maincontext | |
Glib::RefPtr< Glib::MainLoop > | mainloop () |
access the thread's mainloop | |
signal_f< Glib::SignalIdle > | make_idle_signal_f () |
Make a signal functor that returns the glib idle signal. | |
signal_f< Glib::SignalTimeout > | make_timeout_signal_f () |
Make a signal functor that returns the glib timeout signal. | |
signal_f< Glib::SignalIO > | make_io_signal_f () |
Make a signal functor that returns the glib IO signal. | |
signal_f< Glib::SignalChildWatch > | make_childwatch_signal_f () |
Make a signal functor that returns the glib childwatch signal. |
A useful and convenient thread wrapper for Glib threads.
A glib_threadable is used as a baseclass handling the major part of dealing with Glib threads in a threadsafe manner. It encapsulates starting and ending the thread, setting and cleaning up a Glib::MainContext and Glib::MainLoop for the thread and a sigx::dispatcher.
Derived classes just need a request interface and a signal interface other threads can connect to. The request interface consists of methods instructing the thread to do something by tunneling a message with sigx::open_tunnel() to a thread private request handler method that gets called when the message gets dispatched.
The thread in turn emits a signal that it has successfully (or not) completed the task. All thread's connected to that signal then know of the thread's attempt to execute the request.
A glib_threadable uses a sigx::glib_dispatcher (that in turn uses a Glib::Dispatcher) to dispatch requests in a threadsafe manner.
See the following code example to get an idea how to derive from glib_threadable and its usage.
class MyThread: public sigx::glib_threadable { protected: typedef sigc::signal<void, bool> signal_did_something_t; private: struct ThreadPrivate { signal_did_something_t m_sigDidSomething; }; private: Glib::Private<ThreadPrivate> m_threadpriv; public: MyThread(); // request interface sigx::request_f<> do_something; // signal interface; // return a sigx::signal_wrapper for threadsafe access to the signal did_something sigx::signal_f<signal_did_something_t> signal_did_something; protected: // virtuals from threadable virtual void on_startup(); // dispatcher methods, get called when requests of the request interface // get dispatched void on_do_something(); }; MyThread::MyThread(): m_threadpriv(), // initialize request interface do_something(sigc::mem_fun(this, &MyThread::on_do_something)), // initialize signal interface signal_did_something(this, m_threadpriv, &ThreadPrivate::m_sigDidSomething) {} void MyThread::on_startup() { m_threadpriv.set(new ThreadPrivate); } void MyThread::on_do_something() { // do something // ... // broadcast that I have done something const success = true; ThreadPrivate* privdata = m_threadpriv.get(); privdata->m_sigDidSomething.emit(success); }
When a glib_threadable is instantiated the thread does not immediately start its execution. You have to start it explicitly by calling run().
sigx::glib_threadable::glib_threadable | ( | ) |
Constructs the threadable object.
sigx::glib_threadable::~glib_threadable | ( | ) | [virtual] |
dtor.
References sigx::safe_lockable< T_type, T_mutex >::access_nonvolatile().
void sigx::glib_threadable::finish | ( | ) |
Ends the thread, joins it and frees all its resources.
Waits for the main loop to quit and joins the thread and in the process deleting all the thread private data associated with this thread and all the internal resources. You MUST call finish() before deleting a class derived from glib_threadable.
Calling finish() from multiple threads is thread safe;
References mainloop(), and sigx::open_tunnel_with().
Glib::RefPtr< Glib::MainContext > sigx::glib_threadable::maincontext | ( | ) | [protected] |
access the thread's maincontext
Referenced by make_childwatch_signal_f(), make_idle_signal_f(), make_io_signal_f(), and make_timeout_signal_f().
Glib::RefPtr< Glib::MainLoop > sigx::glib_threadable::mainloop | ( | ) | [protected] |
access the thread's mainloop
Referenced by finish().
signal_f<Glib::SignalChildWatch> sigx::glib_threadable::make_childwatch_signal_f | ( | ) | [inline, protected] |
Make a signal functor that returns the glib childwatch signal.
References maincontext().
signal_f<Glib::SignalIdle> sigx::glib_threadable::make_idle_signal_f | ( | ) | [inline, protected] |
Make a signal functor that returns the glib idle signal.
References maincontext().
signal_f<Glib::SignalIO> sigx::glib_threadable::make_io_signal_f | ( | ) | [inline, protected] |
Make a signal functor that returns the glib IO signal.
References maincontext().
signal_f<Glib::SignalTimeout> sigx::glib_threadable::make_timeout_signal_f | ( | ) | [inline, protected] |
Make a signal functor that returns the glib timeout signal.
References maincontext().
void sigx::glib_threadable::run | ( | const T_functor & | func_on_thread_ready | ) |
Creates a joinable thread.
Start the main loop of the thread. The function returns as soon as the thread is created which does not mean that it is already in a running state. To get notified that it is running you pass in a functor (func_on_thread_ready) that gets called as soon as the thread is in a running state.
func_on_thread_ready | a functor that gets called as soon as the thread is idle and ready. The passed in functor is tunneled automatically if not yet a tunnel_functor. Must be convertible to a sigc::slot<void>. |
MyThread mythread; mythread.run(sigc::mem_fun(this, &TheGui::on_mythread_ready)); void TheGUI::on_mythread_ready() { // now, the thread if fully set up, idle and ready mythread.signal_did_something().connect( sigc::mem_fun(this, &TheGUI::on_mythread_did_something) ); }
References SIGX_STATIC_ASSERT.
void sigx::glib_threadable::run | ( | ) |
Creates a joinable thread.
Start the main loop of the thread, this will block until the thread has been created and is in a running state.
Afterwards you can connect to the thread's signals.
References sigx::ref().