Re: Is sigc++ emit() thread safe with GTKMM



Lihling Tzuu,

> I like to use sigc++ signal slot to send data from hardware threads 
> to gtkmm gui. I can mutex lock my emit() calls but I'm wondering 
> if it's thread safe in a gtkmm signal environment?  

- I am not really sure what you mean by "hardware threads", but just in
case, I pasted below an example of a thread using Glib::Dispatcher,
following the advice of Robert Caryl.

- This example was taken form a real internal application running in the
company I work. I carried over it a high simplification to get into the
essential issues, so it probably does not compile without errors if you
try!

- The thread checks every 30[s] for new messages in a database. If there
is any, then it calls 'displayMessage()'.

- Inside the call 'companyData->anyMessages()' there is a mutex lock,
since is not the only thread sharing the same data source.

- Take care that 'displayMessage()' is not called directly, instead
through an asynchronous signal dispatch. If you do it directly you will
have an unexpected behavior and surely a crash.

- As you can see, I use Boost threads. I think using Gtkmm threads will
be almost the same. But it shows the Gtkmm and Boost libraries are real
well done C++, so they can operate seamless. 

I hope this helps to you!

Nicolas


Class definition
================

class wMessage: public wBaseDialog
{
 // ------------------------------------------- 
 // ---------------  P U B L I C  -------------
 // -------------------------------------------  

 public:
  wMessage();  
  ~wMessage();  

 void displayMessage();
 
 // ------------------------------------------- 
 // --------------  P R I V A T E  ------------
 // -------------------------------------------  

 private: 
  Glib::Dispatcher signalShowMessage;
  bool run;
  boost::thread *loop;  
  void loopTask();  
};

And the implementation for each method
======================================

// Boost
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/bind.hpp>

wMessage::wMessage()
{
 signalShowMessage.connect(sigc::mem_fun(*this,
&wMessage::displayMessage)); 
 run= true;
 loop= new boost::thread(boost::bind(&wMessage::loopTask, this));  
}

wMessage::~wMessage()
{
 if(loop!=NULL)
 {
  run= false;
  loop->join(); 
  delete(loop);  
 }  
}

void wMessage::loopTask()
{
 boost::xtime xt;
 while(run)
 {  
  if(companyData->anyMessages())
  {
   signalShowMessage();	   
  }   
  boost::xtime_get(&xt, boost::TIME_UTC);
  xt.sec += 30;  
  boost::thread::sleep(xt);
 }
}

void wMessage::displayMessage()
{
 displayFormData();
}


-- 
Nicolas Slusarenko
Chief Project Officer
www.aplik.com
www.aplik.cl




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]