This class is plainly the encapsulation of Windows event, nothing special, the general practice, and so on another thread is just waiting for the event to believe Waitsingleobject, notify the event is nothing more than setevent, a look on the understanding, not on the detailed, It's written here just for the greater integrity of the system.
The following sample code is noted below:
waitableevent *e = new Waitableevent; Sendtootherthread (e); e->wait (); Delete e;
Sendtootherthread (e); This should be to open another thread or something, and then pass the event past, and then wait until the waiter is done, and then continue, this is not as good as writing the code to write in the current thread, it seems not to understand the meaning of it, the specific use of the scene is better
Copyright (c) the Chromium Authors. All rights reserved.//Use of this source code are governed by a Bsd-style license, can be//found in the license file. #ifndef base_synchronization_waitable_event_h_#define base_synchronization_waitable_event_h_#include "Base/base_ Export.h "#include" base/basictypes.h "#if defined (os_win) #include <windows.h> #endif # if defined (os_posix) # Include <list> #include <utility> #include "base/memory/ref_counted.h" #include "base/synchronization/ Lock.h "#endifnamespace Base {//This replaces INFINITE from win32static const int knotimeout = -1;class timedelta;//A Wai Tableevent can is a useful thread synchronization tool when you want to//allow one thread to wait for another thread to F Inish some work. for//Non-windows Systems, this can is used from within a single address//space.////use a waitableevent when you wo Uld otherwise use a lock+conditionvariable to//protect a simple Boolean value. However, if you find yourself using aWaitableevent in conjunction with a Lock to wait for a more complex state//change (e.g. Queue), then you should probably//is using a conditionvariable instead of a waitableevent.////note:on Windows, this CLA SS provides a subset of the functionality afforded//by a Windows event object. This is intentional. If You is writing windows//specific code and you need other features of a Windows event, then you might//be better off Just using a Windows event Directly.class base_export waitableevent {public://If Manual_reset are true, then to set th E event state to non-signaled, a//consumer must call the Reset method. If This parameter was false, then the//system automatically resets the event state to non-signaled after a single//WA Iting thread has been released. Waitableevent (bool Manual_reset, bool initially_signaled); #if defined (Os_win)//Create a waitableevent from an Event HAN DLE which has already been//created. This objects takes ownership of the HANDLE and would close it when//deleted. Explicit Waitableevent (HANDLE event_handle); Releases ownership of the handle from this object. HANDLE Release (); #endif ~waitableevent (); Put the event in the un-signaled state. void Reset (); Put the event in the signaled state. Causing any thread blocked on Wait//To be woken up. void Signal (); Returns True if the event is in the signaled state, else false. If this//isn't a manual reset event, then this test would cause a reset. BOOL Issignaled (); Wait indefinitely for the event to be signaled. Wait ' s return "happens//after" | signal| has completed. This means it's safe for A//waitableevent to synchronise its own destruction, like this:////Waitableevent * e = new Waitableevent; Sendtootherthread (e); E->wait (); Delete e; void Wait (); Wait up until Max_time have passed for the event to be signaled. Returns//True if the event was signaled. If this MEthod returns FALSE, then it//does wasn't necessarily mean that max_time was exceeded. Timedwait can synchronise its own destruction like | Wait|. BOOL Timedwait (const timedelta& max_time), #if defined (os_win) HANDLE HANDLE () const {return handle_;} #endif//Wait, synchronously, on multiple events. Waitables:an array of waitableevent pointers//count:the number of elements in @waitables////Returns:the Index of a waitableevent which has been signaled. You must not delete any of the Waitableevent objects while this wait is//happening, however Waitmany ' s return ' H Appens after "the | signal| Call//That caused it have completed, like | Wait|. Static size_t Waitmany (waitableevent** waitables, size_t count); For asynchronous waiting, see Waitableeventwatcher//This is a private helper class. It's here because it's used by friends of//This class (such as Waitableeventwatcher) to being able to enqueue elements// of the Wait-list class waiter {public://Signal The waiter to wake up. Consider the case of a waiter which are in multiple waitableevent ' s//wait-lists. Each waitableevent is automatic-reset and both of them is//signaled at the same time. Now, each would wake only the first waiter in//the wake-list before resetting. However, if those, waiters happen to//is the same object (as can happen if another thread didn ' t has a chance To dequeue the waiter from the other wait-list in time), auto-resets//would has happened, but only one waiter has been signaled! Because of this, a waiter could "reject" a wake by returning false. In//This case, the Auto-reset waitableevent shouldn ' t act as if anything have//been notified. virtual bool Fire (waitableevent* signaling_event) = 0; Waiters may implement this on order to provide a extra condition for//both waiters to be considered equal. In waitableevent::D equeue, if the//pointers match ThenThis function is called as a final check. See the//comments in ~handle for why. virtual bool Compare (void* tag) = 0; Protected:virtual ~waiter () {}}; Private:friend class Waitableeventwatcher; #if defined (Os_win) HANDLE handle_; #else//On Windows, one can close a HAND LE which is currently being waited on. The//MSDN documentation says that the resulting behaviour are ' undefined ', but//it doesn ' t crash. However, if we were to include the following members//directly then, on POSIX, one couldn ' t with Waitableeventwatcher to Watch AN//event which gets deleted. This mismatch had bitten us several times now,//So we had a kernel of the waitableevent, which is reference counted. Waitableeventwatchers reference and thus match the Windows//behaviour. struct Waitableeventkernel:public refcountedthreadsafe<waitableeventkernel> {Public:waitableeventkerne L (bool Manual_reset, bool initially_signaled); BOOL Dequeue (waiter* Waiter, void* tag); Base::lock Lock_; const BOOL Manual_reset_; BOOL Signaled_; Std::list<waiter*> Waiters_; Private:friend class refcountedthreadsafe<waitableeventkernel>; ~waitableeventkernel (); }; typedef std::p air<waitableevent*, size_t> waiterandindex; When dealing with arrays of waitableevent*, we want to sort by the address//of the waitableevent in order to has a Globally consistent locking order. In this case we keep them, in sorted order, in a array of pairs where the//second element is the index of the Waita Bleevent in the original,//unsorted, array. Static size_t Enqueuemany (waiterandindex* waitables, size_t count, waiter* waiter); BOOL Signalall (); BOOL Signalone (); void Enqueue (waiter* waiter); Scoped_refptr<waitableeventkernel> kernel_; #endif disallow_copy_and_assign (waitableevent);};} namespace Base#endif//Base_synchronization_waitable_event_h_
Waitableevent in the Google Base library