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.
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.
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(); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With