glib_threadable.h
Go to the documentation of this file.00001 #ifndef _SIGX_GLIB_THREADABLE_HPP_
00002 #define _SIGX_GLIB_THREADABLE_HPP_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <sigc++/functors/slot.h>
00024 #include <glibmm/refptr.h>
00025 #include <glibmm/thread.h>
00026 #include <glibmm/main.h>
00027 #include <sigxconfig.h>
00028 #include <sigx/threadable.h>
00029 #include <sigx/tunnel_functor.h>
00030 #include <sigx/lockable.h>
00031 #include <sigx/volatile_trait.h>
00032 #include <sigx/signal_f.h>
00033
00034
00035
00036 namespace sigx
00037 {
00038
00130 class SIGX_API glib_threadable: public threadable
00131 {
00132 public:
00136 glib_threadable();
00137
00141 virtual ~glib_threadable();
00142
00176 template<typename T_functor>
00177 void run(const T_functor& func_on_thread_ready);
00178
00190 void run();
00191
00209 void finish();
00210
00211
00212 private:
00215 void create_thread(const sigc::slot<void>& slot_on_thread_ready);
00216
00224 void on_run(const sigc::slot<void>& slot_on_thread_ready);
00225
00229 void on_idle_and_ready(Glib::Mutex& mtx, Glib::Cond& cond);
00230
00231 protected:
00234 Glib::RefPtr<Glib::MainContext> maincontext();
00235
00238 Glib::RefPtr<Glib::MainLoop> mainloop();
00239
00242 signal_f<Glib::SignalIdle> make_idle_signal_f()
00243 {
00244 return signal_f<Glib::SignalIdle>(
00245
00246 *this,
00247
00248
00249 sigc::compose(
00250
00251 sigc::mem_fun(&Glib::MainContext::signal_idle),
00252
00253 sigc::compose(
00254
00255 sigc::mem_fun(&Glib::RefPtr<Glib::MainContext>::operator ->),
00256
00257 sigc::mem_fun(this, &glib_threadable::maincontext)
00258 )
00259 )
00260 );
00261 }
00262
00265 signal_f<Glib::SignalTimeout> make_timeout_signal_f()
00266 {
00267 return signal_f<Glib::SignalTimeout>(
00268
00269 *this,
00270
00271
00272 sigc::compose(
00273
00274 sigc::mem_fun(&Glib::MainContext::signal_timeout),
00275
00276 sigc::compose(
00277
00278 sigc::mem_fun(&Glib::RefPtr<Glib::MainContext>::operator ->),
00279
00280 sigc::mem_fun(this, &glib_threadable::maincontext)
00281 )
00282 )
00283 );
00284 }
00285
00288 signal_f<Glib::SignalIO> make_io_signal_f()
00289 {
00290 return signal_f<Glib::SignalIO>(
00291
00292 *this,
00293
00294
00295 sigc::compose(
00296
00297 sigc::mem_fun(&Glib::MainContext::signal_io),
00298
00299 sigc::compose(
00300
00301 sigc::mem_fun(&Glib::RefPtr<Glib::MainContext>::operator ->),
00302
00303 sigc::mem_fun(this, &glib_threadable::maincontext)
00304 )
00305 )
00306 );
00307 }
00308
00311 signal_f<Glib::SignalChildWatch> make_childwatch_signal_f()
00312 {
00313 return signal_f<Glib::SignalChildWatch>(
00314
00315 *this,
00316
00317
00318 sigc::compose(
00319
00320 sigc::mem_fun(&Glib::MainContext::signal_child_watch),
00321
00322 sigc::compose(
00323
00324 sigc::mem_fun(&Glib::RefPtr<Glib::MainContext>::operator ->),
00325
00326 sigc::mem_fun(this, &glib_threadable::maincontext)
00327 )
00328 )
00329 );
00330 }
00331
00332
00333 private:
00334 struct threaddata;
00335 Glib::Private<threaddata> m_threaddata;
00336 typedef mutex_lockable<Glib::Thread*> mutex_lockable_thread;
00337 mutex_lockable_thread m_thread;
00338 };
00339
00340
00364 }
00365
00366
00367
00368
00369 #include <sigx/auto_tunneler.h>
00370 #include <sigx/static_assert.h>
00371
00372
00373 namespace sigx
00374 {
00375
00376 template<typename T_functor>
00377 void glib_threadable::run(const T_functor& func_on_thread_ready)
00378 {
00379 typedef internal::auto_tunneler<T_functor> auto_tunneler_t;
00380
00381
00382
00383
00384
00385 SIGX_STATIC_ASSERT((sigx::internal::is_or_adapts_slot<T_functor>::value == false));
00386
00387
00388 SIGX_STATIC_ASSERT((sigc::is_base_and_derived<tunnel_base, typename auto_tunneler_t::functor_type>::value == true));
00389
00390 const typename auto_tunneler_t::functor_type& functor2callback =
00391 auto_tunneler_t::auto_open_tunnel(func_on_thread_ready);
00392
00393
00394
00395
00396
00397 create_thread(sigc::slot<void>(functor2callback));
00398 }
00399
00400
00401 }
00402
00403
00404 #endif // end file guard