Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cross-Platform equivalent to windows events

Tags:

I'm trying to port some Windows code to Linux, ideally through platform-independent libraries (eg boost), however I'm not sure how to port this bit of event code.

The bit of code involves two threads (lets call them A and B). A wants to do something that only B can, so it sends B a message, then waits for B to say its done. In windows this looks something like:

void foo();//thread a calls this void bar(HANDLE evt);  void foo() {     HANDLE evt = CreateEvent(0,FALSE,FALSE,0);     bCall(boost::bind(&bar, evt));     WaitForSingleObject(evt,INFINITE);     CloseHandle(evt); } void bar(HANDLE evt) {     doSomething();     SetEvent(evt); } 

I looked at the boost::thread library, but it didnt seem to have anything that does this, the closes I could see was the boost::condition_variable, but it appears that is means in conjunction with a mutex, which is not the case here.

like image 442
Fire Lancer Avatar asked Nov 04 '09 22:11

Fire Lancer


2 Answers

All these answers are too complex, come on people it isn't that hard.

namespace porting {    class Event;    typedef Event* Event_handle;    static const unsigned k_INFINITE = 0xFFFFFFFF;     class Event    {       friend Event_handle CreateEvent( void );       friend void CloseHandle( Event_handle evt );       friend void SetEvent( Event_handle evt );       friend void WaitForSingleObject( Event_handle evt, unsigned timeout );        Event( void ) : m_bool(false) { }        bool m_bool;       boost::mutex m_mutex;       boost::condition m_condition;    };     Event_handle CreateEvent( void )    { return new Event; }     void CloseHandle( Event_handle evt )    { delete evt; }     void SetEvent( Event_handle evt )    {       evt->m_bool = true;       evt->m_cond.notify_all();    }     void WaitForSingleObject( Event_handle evt, unsigned timeout )    {       boost::scoped_lock lock( evt->m_mutex );       if( timeout == k_INFINITE )       {          while( !evt->m_bool )          {             evt->m_cond.wait( lock );          }       }       else       {          //slightly more complex code for timeouts       }    }  }// porting  void foo() {    porting::Event_handle evt = porting::CreateEvent();    bCall( boost::bind(&bar, evt ) );    porting::WaitForSingleObject( evt, porting::k_INFINITE );    porting::CloseHandle(evt); }  void bar( porting::Event_handle evt ) {    doSomething();    porting::SetEvent(evt); } 

There is probably a bit more to do to get this fully working as I'm not familiar with the semantics of WaitForSingleObject (what happens if two threads call it at the same time, what happens if the same thread calls it twice). However, the solution will look very much like this.

like image 129
deft_code Avatar answered Sep 21 '22 06:09

deft_code


I think a good, cross-platform equivalent to win32 events is boost::condition, so your code could look something like this:

void foo() {     boost::mutex mtxWait;      boost::condition cndSignal;      bCall(boost::bind(&bar, mtxWait, cndSignal));      boost::mutex::scoped_lock mtxWaitLock(mtxWait);     cndSignal.wait(mtxWait); // you could also use cndSignal.timed_wait() here }  void bar(boost::mutex& mtxWait, boost::condition& cndSignal) {     doSomething();     cndSignal.notify_one(); } 
like image 33
Alan Avatar answered Sep 22 '22 06:09

Alan