second and last example in glibmm/examples/thread that didn't compile fixed... On mié, 2003-10-01 at 03:06, Murray Cumming wrote: > On Wed, 2003-10-01 at 01:43, J Abelardo Gutierrez wrote: > > This is great news, I use glib for all my my non gui C apps and now I > > will use glimm for all my c++ ones. > > Yes, libxml++ will also use it in future. > > > If there is some work I could contribute with ... > > There are 1 or 2 examples in glibmm 2.4 that don't build because they > use gtkmm. For instance, examples/thread. I'd really like someone to > remove the GUI from them. > > And we need to find out whether any API has been added to glib 2.3 in > CVS, or will be added. -- Lic. J. Abelardo Gutierrez Linux Counter # 80026 -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/MU dx s-:++>-: a C+++ UL+++$ P++>+++ L+++>++++ E-- W+ N o K- w---(+)$ O+>- M? V? PS+ PE- Y+ PGP>+ t 5 X+ R+ tv+ b++ DI(+) D++ G e++ h r+++ y+++ ------END GEEK CODE BLOCK------
/* * original Glib::Dispatcher example -- cross thread signalling * by Daniel Elstner <daniel elstner gmx net> * * Modified by Stephan Puchegger <stephan puchegger ap univie ac at> * to contain 2 mainloops in 2 different threads, that communicate * via cross thread signalling in both directions. The timer thread * sends the UI thread a cross thread signal every second, which in turn * updates the label stating how many seconds have passed since the start * of the program. * * Modified by J. Abelardo Gutierrez <jabelardo cantv net> * to cast all gtkmm out and make it glimm only * * Note: This example is special stuff that's seldomly needed by the * vast majority of applications. Don't bother working out what this * code does unless you know for sure you need 2 main loops running in * 2 distinct main contexts. * * Copyright (c) 2002-2003 Free Software Foundation */ #include <sigc++/class_slot.h> #include <glibmm.h> #include <sstream> #include <iostream> namespace { Glib::RefPtr<Glib::MainLoop> main_loop; class ThreadTimer : public SigC::Object { public: ThreadTimer(); ~ThreadTimer(); void launch(); void signal_finished_emit(); void print() const; static SigC::Signal0< void >& signal_end(); private: guint time_; Glib::Dispatcher signal_increment_; Glib::Dispatcher* signal_finished_ptr_; Glib::Mutex startup_mutex_; Glib::Cond startup_cond_; static SigC::Signal0< void > signal_end_; Glib::Thread* thread_; void timer_increment(); bool timeout_handler(); static void finished_handler( Glib::RefPtr<Glib::MainLoop> mainloop ); void thread_function(); }; class Dispatcher : public SigC::Object { public: Dispatcher(); void launch_thread(); void end(); private: ThreadTimer* timer_; }; ThreadTimer::ThreadTimer() : time_( 0 ), // Create a new dispatcher that is attached to the default main context, signal_increment_(), // This pointer will be initialized later by the 2nd thread. signal_finished_ptr_( NULL ) { // Connect the cross-thread signal. signal_increment_.connect( SigC::slot( *this, &ThreadTimer::timer_increment ) ); } ThreadTimer::~ThreadTimer() {} void ThreadTimer::launch() { // Unfortunately, the thread creation has to be fully synchronized in // order to access the Dispatcher object instantiated by the 2nd thread. // So, let's do some kind of hand-shake using a mutex and a condition // variable. Glib::Mutex::Lock lock( startup_mutex_ ); // Create a joinable thread -- it needs to be joined, otherwise it's a memory leak. thread_ = Glib::Thread::create( SigC::slot_class( *this, &ThreadTimer::thread_function ), true ); // Wait for the 2nd thread's startup notification. while ( signal_finished_ptr_ == NULL ) { startup_cond_.wait( startup_mutex_ ); } } void ThreadTimer::signal_finished_emit() { // Cause the 2nd thread's main loop to quit. signal_finished_ptr_->emit(); // wait for the thread to join if ( thread_ != NULL ) { thread_->join(); } signal_finished_ptr_ = NULL; } void ThreadTimer::print() const { std::cout << time_ << " seconds since start" << std::endl; } SigC::Signal0< void >& ThreadTimer::signal_end() { return signal_end_; } void ThreadTimer::timer_increment() { // another second has passed since the start of the program ++time_; print(); if ( time_ >= 10 ) { signal_finished_emit(); } } // static void ThreadTimer::finished_handler( Glib::RefPtr<Glib::MainLoop> mainloop ) { // quit the timer thread mainloop mainloop->quit(); std::cout << "timer thread mainloop finished" << std::endl; ThreadTimer::signal_end().emit(); } bool ThreadTimer::timeout_handler() { // inform the printing thread that another second has passed signal_increment_(); // this timer should stay alive return true; } void ThreadTimer::thread_function() { // create a new Main Context Glib::RefPtr<Glib::MainContext> context = Glib::MainContext::create(); // create a new Main Loop Glib::RefPtr<Glib::MainLoop> mainloop = Glib::MainLoop::create( context, true ); // attach a timeout handler, that is called every second, to the // newly created MainContext context->signal_timeout().connect( SigC::slot( *this, &ThreadTimer::timeout_handler ), 1000 ); // We need to lock while creating the Dispatcher instance, // in order to ensure memory visibility. Glib::Mutex::Lock lock ( startup_mutex_ ) ; // create a new dispatcher, that is connected to the newly // created MainContext Glib::Dispatcher signal_finished ( context ); signal_finished.connect( SigC::bind( SigC::slot( &ThreadTimer::finished_handler ), mainloop ) ); signal_finished_ptr_ = &signal_finished; // Tell the launcher thread that everything is in place now. startup_cond_.signal(); lock.release(); // start the mainloop mainloop->run(); } // static SigC::Signal0< void > ThreadTimer::signal_end_; Dispatcher::Dispatcher() : timer_ ( NULL ) { std::cout << "Thread Dispatcher Example #2" << std::endl; timer_ = new ThreadTimer(); timer_->signal_end().connect( SigC::slot( *this, &Dispatcher::end ) ); timer_->print(); } void Dispatcher::launch_thread() { // launch the timer thread timer_->launch(); } void Dispatcher::end() { // quit the main mainloop main_loop->quit(); } } // anonymous namespace int main( gint argc, gchar** argv ) { Glib::thread_init(); main_loop = Glib::MainLoop::create(); Dispatcher dispatcher; // Install a one-shot idle handler to launch the threads Glib::signal_idle().connect( SigC::bind_return( SigC::slot( dispatcher, &Dispatcher::launch_thread ), false ) ); main_loop->run(); return 0; }
Attachment:
signature.asc
Description: This is a digitally signed message part