27#if ! GCONFIG_HAVE_WINDOWS_CREATE_EVENT_EX
28HANDLE CreateEventEx( LPSECURITY_ATTRIBUTES sec , LPCTSTR name , DWORD flags , DWORD )
30 BOOL manual_reset = ( flags & 1 ) ? TRUE : FALSE ;
31 BOOL initial_state = ( flags & 2 ) ? TRUE : FALSE ;
32 return CreateEvent( sec , manual_reset , initial_state , name ) ;
36#ifndef CREATE_EVENT_MANUAL_RESET
37#define CREATE_EVENT_MANUAL_RESET 1
40class GNet::FutureEventImp :
public EventHandler
43 FutureEventImp( FutureEventHandler & handler , EventState es ) ;
46 ~FutureEventImp()
override ;
49 static bool send( HANDLE ,
bool ) noexcept ;
52 HANDLE handle() noexcept ;
56 void readEvent() override ;
59 FutureEventImp( const FutureEventImp & ) = delete ;
60 FutureEventImp( FutureEventImp && ) = delete ;
61 FutureEventImp & operator=( const FutureEventImp & ) = delete ;
62 FutureEventImp & operator=( FutureEventImp && ) = delete ;
71 ~Handle() {
if(h) CloseHandle(h) ; }
72 Handle & operator=( HANDLE h_ ) { h = h_ ;
return *this ; }
73 bool operator==( HANDLE h_ )
const {
return h == h_ ; }
74 Handle(
const Handle & ) = delete ;
75 Handle( Handle && ) = delete ;
76 Handle & operator=(
const Handle & ) = delete ;
77 Handle & operator=( Handle && ) = delete ;
82 FutureEventHandler & m_handler ;
88GNet::FutureEventImp::FutureEventImp( FutureEventHandler & handler , EventState es ) :
92 m_h = FutureEvent::createHandle() ;
94 throw FutureEvent::Error(
"CreateEventEx" ) ;
98 EventLoop::instance().addRead( Descriptor(INVALID_SOCKET,m_h.h) , *
this , es ) ;
101GNet::FutureEventImp::~FutureEventImp()
103 if( EventLoop::exists() )
104 EventLoop::instance().dropRead( Descriptor(INVALID_SOCKET,m_h.h) ) ;
107HANDLE GNet::FutureEventImp::dup()
113 BOOL ok = DuplicateHandle(
114 GetCurrentProcess() , m_h.h ,
115 GetCurrentProcess() , &h ,
116 0 , FALSE , DUPLICATE_SAME_ACCESS ) ;
119 DWORD e = GetLastError() ;
120 throw FutureEvent::Error(
"DuplicateHandle" ,
G::Str::fromUInt(
static_cast<unsigned int>(e)) ) ;
125HANDLE GNet::FutureEventImp::handle() noexcept
128 std::swap( h2 , m_h2.h ) ;
132bool GNet::FutureEventImp::send( HANDLE handle ,
bool close )
noexcept
134 bool ok = SetEvent( handle ) != 0 ;
136 CloseHandle( handle ) ;
142 G_DEBUG(
"GNet::FutureEventImp::readEvent: future event: h=" << m_h.h ) ;
143 m_handler.onFutureEvent() ;
149 m_imp(
std::make_unique<FutureEventImp>(handler,es))
158 return FutureEventImp::send( handle , close ) ;
163 return m_imp->handle() ;
168 const DWORD access = DELETE | SYNCHRONIZE | EVENT_MODIFY_STATE | PROCESS_DUP_HANDLE ;
169 return CreateEventEx(
nullptr ,
nullptr , CREATE_EVENT_MANUAL_RESET , access ) ;
virtual void readEvent()
Called for a read event.
FutureEvent(FutureEventHandler &, EventState)
Constructor. Installs itself in the event loop.
static bool send(HANDLE handle, bool close=true) noexcept
Pokes an event into the main event loop so that the FutureEventHandler callback is called asynchronou...
HANDLE handle() noexcept
Extracts a handle that can be passed between threads and used in send().
static HANDLE createHandle()
Used by some event loop implementations to create the underlying synchronisation object.
~FutureEvent()
Destructor.
static std::string fromUInt(unsigned int ui)
Converts unsigned int 'ui' to a string.