diff options
Diffstat (limited to 'src/gc/env/gcenv.os.h')
-rw-r--r-- | src/gc/env/gcenv.os.h | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/gc/env/gcenv.os.h b/src/gc/env/gcenv.os.h index 6a126f29ed..d3e40ac4ff 100644 --- a/src/gc/env/gcenv.os.h +++ b/src/gc/env/gcenv.os.h @@ -47,6 +47,86 @@ struct GCThreadAffinity int Processor; }; +// An event is a synchronization object whose state can be set and reset +// indicating that an event has occured. It is used pervasively throughout +// the GC. +// +// Note that GCEvent deliberately leaks its contents by not having a non-trivial destructor. +// This is by design; since all uses of GCEvent have static lifetime, their destructors +// are run on process exit, potentially concurrently with other threads that may still be +// operating on the static event. To avoid these sorts of unsafety, GCEvent chooses to +// not have a destructor at all. The cost of this is leaking a small amount of memory, but +// this is not a problem since a majority of the uses of GCEvent are static. See CoreCLR#11111 +// for more details on the hazards of static destructors. +class GCEvent { +private: + class Impl; + Impl *m_impl; + +public: + // Constructs a new uninitialized event. + GCEvent(); + + // Closes the event. Attempting to use the event past calling CloseEvent + // is a logic error. + void CloseEvent(); + + // "Sets" the event, indicating that a particular event has occured. May + // wake up other threads waiting on this event. Depending on whether or + // not this event is an auto-reset event, the state of the event may + // or may not be automatically reset after Set is called. + void Set(); + + // Resets the event, resetting it back to a non-signalled state. Auto-reset + // events automatically reset once the event is set, while manual-reset + // events do not reset until Reset is called. It is a no-op to call Reset + // on an auto-reset event. + void Reset(); + + // Waits for some period of time for this event to be signalled. The + // period of time may be infinite (if the timeout argument is INFINITE) or + // it may be a specified period of time, in milliseconds. + // Returns: + // One of three values, depending on how why this thread was awoken: + // WAIT_OBJECT_0 - This event was signalled and woke up this thread. + // WAIT_TIMEOUT - The timeout interval expired without this event being signalled. + // WAIT_FAILED - The wait failed. + uint32_t Wait(uint32_t timeout, bool alertable); + + // Determines whether or not this event is valid. + // Returns: + // true if this event is invalid (i.e. it has not yet been initialized or + // has already been closed), false otherwise + bool IsValid() const + { + return m_impl != nullptr; + } + + // Initializes this event to be a host-aware manual reset event with the + // given initial state. + // Returns: + // true if the initialization succeeded, false if it did not + bool CreateManualEventNoThrow(bool initialState); + + // Initializes this event to be a host-aware auto-resetting event with the + // given initial state. + // Returns: + // true if the initialization succeeded, false if it did not + bool CreateAutoEventNoThrow(bool initialState); + + // Initializes this event to be a host-unaware manual reset event with the + // given initial state. + // Returns: + // true if the initialization succeeded, false if it did not + bool CreateOSManualEventNoThrow(bool initialState); + + // Initializes this event to be a host-unaware auto-resetting event with the + // given initial state. + // Returns: + // true if the initialization succeeded, false if it did not + bool CreateOSAutoEventNoThrow(bool initialState); +}; + // GC thread function prototype typedef void (*GCThreadFunction)(void* param); |