sigx++  2.0.1
glib_threadable.h
Go to the documentation of this file.
1 #ifndef _SIGX_GLIB_THREADABLE_HPP_
2 #define _SIGX_GLIB_THREADABLE_HPP_
3 
4 /*
5  * Copyright 2006 Klaus Triendl
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the Free
19  * Software Foundation, 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21 */
22 
23 #include <sigc++/functors/slot.h>
24 #include <glibmm/refptr.h>
25 #include <glibmm/thread.h>
26 #include <glibmm/main.h>
27 #include <sigxconfig.h>
28 #include <sigx/threadable.h>
29 #include <sigx/tunnel_functor.h>
30 #include <sigx/lockable.h>
31 #include <sigx/volatile_trait.h>
32 #include <sigx/signal_f.h>
33 
34 
35 
36 namespace sigx
37 {
38 
130 class SIGX_API glib_threadable: public threadable
131 {
132 public:
136  glib_threadable();
137 
141  virtual ~glib_threadable();
142 
176  template<typename T_functor>
177  void run(const T_functor& func_on_thread_ready);
178 
190  void run();
191 
209  void finish();
210 
211 
212 private:
215  void create_thread(const sigc::slot<void>& slot_on_thread_ready);
216 
224  void on_run(const sigc::slot<void>& slot_on_thread_ready);
225 
229  void on_idle_and_ready(Glib::Mutex& mtx, Glib::Cond& cond);
230 
231 protected:
234  Glib::RefPtr<Glib::MainContext> maincontext();
235 
238  Glib::RefPtr<Glib::MainLoop> mainloop();
239 
243  {
245  // the dispatchable
246  *this,
247  // the signal source is a functor executing
248  // this->maincontext()->signal_idle()
249  sigc::compose(
250  // setter
251  sigc::mem_fun(&Glib::MainContext::signal_idle),
252  // getter
253  sigc::compose(
254  // setter
255  sigc::mem_fun(&Glib::RefPtr<Glib::MainContext>::operator ->),
256  // getter
257  sigc::mem_fun(this, &glib_threadable::maincontext)
258  )
259  )
260  );
261  }
262 
266  {
268  // the dispatchable
269  *this,
270  // the signal source is a functor executing
271  // this->maincontext()->signal_timeout()
272  sigc::compose(
273  // setter
274  sigc::mem_fun(&Glib::MainContext::signal_timeout),
275  // getter
276  sigc::compose(
277  // setter
278  sigc::mem_fun(&Glib::RefPtr<Glib::MainContext>::operator ->),
279  // getter
280  sigc::mem_fun(this, &glib_threadable::maincontext)
281  )
282  )
283  );
284  }
285 
289  {
291  // the dispatchable
292  *this,
293  // the signal source is a functor executing
294  // this->maincontext()->signal_io()
295  sigc::compose(
296  // setter
297  sigc::mem_fun(&Glib::MainContext::signal_io),
298  // getter
299  sigc::compose(
300  // setter
301  sigc::mem_fun(&Glib::RefPtr<Glib::MainContext>::operator ->),
302  // getter
303  sigc::mem_fun(this, &glib_threadable::maincontext)
304  )
305  )
306  );
307  }
308 
312  {
314  // the dispatchable
315  *this,
316  // the signal source is a functor executing
317  // this->maincontext()->signal_childwatch()
318  sigc::compose(
319  // setter
320  sigc::mem_fun(&Glib::MainContext::signal_child_watch),
321  // getter
322  sigc::compose(
323  // setter
324  sigc::mem_fun(&Glib::RefPtr<Glib::MainContext>::operator ->),
325  // getter
326  sigc::mem_fun(this, &glib_threadable::maincontext)
327  )
328  )
329  );
330  }
331 
332 
333 private:
334  struct threaddata;
335  Glib::Private<threaddata> m_threaddata;
336  typedef mutex_lockable<Glib::Thread*> mutex_lockable_thread;
337  mutex_lockable_thread m_thread;
338 };
339 
340 
364 } // namespace sigx
365 
366 
367 
368 
369 #include <sigx/auto_tunneler.h>
370 #include <sigx/static_assert.h>
371 
372 
373 namespace sigx
374 {
375 
376 template<typename T_functor>
377 void glib_threadable::run(const T_functor& func_on_thread_ready)
378 {
379  typedef internal::auto_tunneler<T_functor> auto_tunneler_t;
380 
381  // passed in functor must not be a slot or adapt a slot;
382  // we have to apply this restriction because slots might have bound
383  // trackables that can cause non-threadsafe access to the passed in slot
384  // which will live in the context of the server thread
386 
387  // toplevel functor must be a tunnel functor
388  SIGX_STATIC_ASSERT((sigc::is_base_and_derived<tunnel_base, typename auto_tunneler_t::functor_type>::value == true));
389 
390  const typename auto_tunneler_t::functor_type& functor2callback =
391  auto_tunneler_t::auto_open_tunnel(func_on_thread_ready);
392 
393  // a sigc::slot is created out of the functor func_on_thread_ready and bound
394  // to another functor suitable for Glib::Thread::create.
395  // this still happens in the context of the calling thread and is therefore
396  // threadsafe
397  create_thread(sigc::slot<void>(functor2callback));
398 }
399 
400 
401 } // namespace sigx
402 
403 
404 #endif // end file guard
finds out whether T_functor is tunneled, i.e. whether the functor chain contains a functor derived fr...
Definition: internal_types.h:176
Derived classes denote that they are a thread wrapper.
Definition: threadable.h:42
Definition: fwddecl.h:37
signal_f< Glib::SignalIO > make_io_signal_f()
Make a signal functor that returns the glib IO signal.
Definition: glib_threadable.h:288
Automatic creation of a tunnel functor if T_functor is not yet tunneled.
Definition: auto_tunneler.h:41
signal_f< Glib::SignalChildWatch > make_childwatch_signal_f()
Make a signal functor that returns the glib childwatch signal.
Definition: glib_threadable.h:311
signal_f< Glib::SignalIdle > make_idle_signal_f()
Make a signal functor that returns the glib idle signal.
Definition: glib_threadable.h:242
void run()
Creates a joinable thread.
Definition: glib_threadable.cpp:62
A useful and convenient thread wrapper for Glib threads.
Definition: glib_threadable.h:130
#define SIGX_STATIC_ASSERT(expr)
Definition: static_assert.h:53
signal_f< Glib::SignalTimeout > make_timeout_signal_f()
Make a signal functor that returns the glib timeout signal.
Definition: glib_threadable.h:265
Glib::RefPtr< Glib::MainContext > maincontext()
access the thread's maincontext
Definition: glib_threadable.cpp:52
Functor returning a sigx::signal_wrapper as a threadsafe signal wrapper.
Definition: signal_f.h:121