| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- /* Copyright The kNet Project.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License. */
- #pragma once
- /** @file Event.h
- @brief The class \ref kNet::Event Event. Provides a mechanism for inter-thread signalling. */
- #ifdef WIN32
- #include "win32/WS2Include.h"
- #endif
- namespace kNet
- {
- enum EventWaitType
- {
- EventWaitInvalid, ///< This event is uninitialized.
- EventWaitDummy, ///< The event to be waited on is a dummy event. Used to keep the index numbers straight, to avoid a O(n) pass through the whole event wait list.
- EventWaitSignal, ///< The event to be waited on is not a socket-based event, but an application-triggered signal event.
- EventWaitRead, ///< The event to be waited on is a socket read event.
- EventWaitWrite ///< The event to be waited on is a socket write event.
- };
- /// Event is an inter-thread synchronization primitive that can be in one of two states: Set or Cleared.
- /** A thread can avoid busy-waiting on a condition by using an Event to represent the triggering of that condition
- and calling its \ref kNet::Event::Wait "Wait()" function to observe when the condition occurs.
- Network socket read and write availability can be represented as an Event as well. The \ref kNet::EventArray
- EventArray class can be used to wait on list of events. This allows a mixture of socket and application events to
- be handled using a single select() call.
- To create a new event, call \ref kNet::CreateNewEvent CreateNewEvent with the wait type of EventWaitSignal.
- The Event class does not follow RAII or data sharing patterns to avoid thread-safety issues. Therefore it is important
- to note that:
- - The default ctor initializes a "null" event - one that is not initialized.
- - The default copy-ctor copies the event. The two events will be the same, i.e. does not matter which of them to wait or signal.
- - The default assignment operator also copies the event, but does NOT free up the internal data used by the old event. When
- assigning over an Event that is not needed any more, call \ref kNet::Event::Close "Close()" on that event.
- - The default destructor of an Event does NOT delete the event. Before letting the last copy of an Event go out of scope,
- manually call \ref kNet::Event::Close "Close()" on that Event.
- This class represents a WSAEVENT on Windows, and socket or a pipe on unix. */
- class Event
- {
- public:
- /// Creates a null event. Call Event::Create to initialize the event.
- Event();
- // Does not delete the event. Call Event::Close() when you don't need it anymore.
- // ~Event();
- /// Initializes the event to a new instance. If the Event was previously initialized, does *not* Close
- /// the old instance.
- void Create(EventWaitType type);
- /// Deinitializes the Event. If there exists any copies of this Event, their state will be undefined.
- void Close();
- /// Returns true if this event is uninitialized.
- bool IsNull() const;
- /// Returns true if this event is not null.
- bool IsValid() const;
- /// Clears the event, i.e. sets it to "0".
- void Reset();
- /// Sets the event, i.e. sets it to "1".
- void Set();
- /// Returns true if the event is in set state.
- bool Test() const;
- /// Returns true if the event was set, or got set during the timeout period, or returns false if the event
- /// was not set before the timeout occurred.
- bool Wait(unsigned long msecs) const;
- /// Returns the underlying type of the event, specifying what kind of system object is being represented by this event.
- EventWaitType Type() const { return type; }
- private:
- EventWaitType type;
- #ifdef WIN32
- public:
- WSAEVENT wsaEvent;
- /// Wraps the given WSAEVENT into this event.
- explicit Event(WSAEVENT wsaEvent, EventWaitType eventType);
- #elif defined(KNET_UNIX) || defined(ANDROID)
- public:
- int fd[2]; // fd[0] is used for reading, fd[1] for writing.
- /// Wraps the given socket file descriptor into this event.
- explicit Event(int /*SOCKET*/ fd, EventWaitType eventType);
- #endif
- };
- /// Creates and returns a new event.
- Event CreateNewEvent(EventWaitType type);
- } // ~kNet
|