/usr/include/x86_64-linux-gnu/qcc/windows/Event.h is in liballjoyn-common-dev-1504 15.04b-8.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 | /**
* @file
*
* Platform independent event implementation
*/
/******************************************************************************
* Copyright AllSeen Alliance. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
******************************************************************************/
#ifndef _OS_QCC_EVENT_H
#define _OS_QCC_EVENT_H
#include <qcc/platform.h>
#include <winsock2.h>
#include <windows.h>
#include <vector>
#include <qcc/atomic.h>
#include <qcc/Mutex.h>
#include <Status.h>
/** @internal */
namespace qcc {
/** @internal Forward Reference */
class Source;
/**
* Events are used to send signals between threads.
*/
class Event {
public:
/** Cause Wait to have no timeout */
static const uint32_t WAIT_FOREVER = static_cast<uint32_t>(-1);
/** Singleton always set Event */
static Event& alwaysSet;
/** Singleton never set Event */
static Event& neverSet;
/** Indicate how to select on file descriptor */
typedef enum {
GEN_PURPOSE, /**< General purpose Windows event backed event */
IO_READ, /**< IO read event */
IO_WRITE, /**< IO write event */
TIMED /**< Event is automatically set based on time */
} EventType;
/**
* Create a general purpose Event.
* General purpose events are manually set and and reset.
*/
Event();
/**
* Create a general purpose Event optionally as
* a network interface event.
* Network interface events are manually reset.
*/
Event(bool networkIfaceEvent);
/**
* Create a timed event.
* Timed events cannot be manually set and reset.
*
* @param delay Number of milliseconds to delay before Event is automatically set.
* @param period Number of milliseconds between auto-set events or 0 to indicate no repeat.
*/
Event(uint32_t delay, uint32_t period = 0);
/**
* Create an event from an existing event.
* This constructor is typically used to create an IO_WRITE type event from an IO_READ one.
* (or vice-versa). Some platforms (windows) do not allow creation of two independent events
* from the same socket descriptor. Thus, this constructor is used for creating the second
* Event (sink or source) rather than using the one that takes a file descriptor as an argument twice.
*
* @param event Event whose underlying source is used a basis for a new event.
* @param genPurpose true if event should act as both an I/O event and a gen purpose event.
*/
Event(Event& event, EventType eventType, bool genPurpose);
/**
* Constructor used by I/O sources/sinks
*
* @param fd Socket descriptor associated with this event.
* @param eventType Type of event (IO_READ or IO_WRITE) associated with fd.
*/
Event(SocketFd fd, EventType eventType);
/**
* Constructor used by Windows specific named pipe I/O sources/sinks.
* (This constructor should only be used within Windows platform specific code.)
*
* @param pipeHandle pipe handle associated with this event.
* @param eventType Type of event (IO_READ or IO_WRITE) associated with pipe.
*/
Event(HANDLE pipeHandle, EventType eventType);
/** Destructor */
~Event();
/**
* Wait on a group of events.
* The call to Wait will return when any of the events on the list is signaled.
*
* @warning There is a subtle difference between Windows and Posix
* implementations of this method. In the Windows case, the return value of
* this method inherits ER_TIMEOUT from any checkEvents that time out; but
* in the posix case ER_OK is returned if one of the checkEvents times out.
* For portable uses of this method consider ER_OK and ER_TIMEOUT as
* indicating success.
*
* @param checkEvents Vector of event object references to wait on.
* @param signaledEvents Vector of event object references from checkEvents that are signaled.
* @param maxMs Max number of milliseconds to wait or WAIT_FOREVER to wait forever.
* @return ER_OK if successful, ER_TIMEOUT if one if the checkEvents times out.
*/
static QStatus AJ_CALL Wait(const std::vector<Event*>& checkEvents, std::vector<Event*>& signaledEvents, uint32_t maxMs = WAIT_FOREVER);
/**
* Wait on a single event.
* The call to Wait will return when the event is signaled.
*
* @param event Event to wait on.
* @param maxMs Max number of milliseconds to wait or WAIT_FOREVER to wait forever.
* @return ER_OK if successful.
*/
static QStatus AJ_CALL Wait(Event& event, uint32_t maxMs = WAIT_FOREVER);
/**
* Release a lock and then wait on a single event.
* The call to Wait will return when the event is signaled.
*
* @param event Event to wait on.
* @param lock The lock to release after incrementing numThreads
* @param maxMs Max number of milliseconds to wait or WAIT_FOREVER to wait forever.
* @return ER_OK if successful.
*/
static QStatus AJ_CALL Wait(Event& event, qcc::Mutex& lock, uint32_t maxMs = WAIT_FOREVER)
{
event.IncrementNumThreads();
lock.Unlock();
QStatus status = Wait(event, maxMs);
event.DecrementNumThreads();
return status;
}
/**
* Set the event to the signaled state.
* All threads that are waiting on the event will become runnable.
* Calling SetEvent when the state is already signaled has no effect.
*
* @return ER_OK if successful.
*/
QStatus SetEvent();
/**
* Indicate whether the event is associated with a socket.
*
* @return true if the event is for sockets, otherwise false.
*/
bool IsSocket() const { return isSocket; }
/**
* Reset the event to the non-signaled state.
* Threads that call wait() will block until the event state becomes signaled.
* Calling ResetEvent() when the state of the event is non-signaled has no effect.
*
* @return ER_OK if successful.
*/
QStatus ResetEvent();
/**
* Indicate whether the event is currently set.
*
* @return true iff event is set.
*/
bool IsSet();
/**
* Reset TIMED event and set next auto-set delay and period.
*
* @param delay Number of milliseconds to delay before Event is automatically set.
* @param period Number of milliseconds between auto-set events or 0 to indicate no repeat.
*/
void ResetTime(uint32_t delay, uint32_t period);
/**
* Get the underlying file descriptor for I/O backed events.
* This returns INVALID_SOCKET_FD if there is no underlying file descriptor.
*
* @return The underlying file descriptor or INVALID_SOCKET_FD.
*/
SocketFd GetFD() const { return ioFd; }
/**
* Get the underlying Windows' event or waitable timer handle. Use of this function is not
* portable and should only be used in platform specific code.
*
* @return The underlying event or waitable timer handle.
*/
HANDLE GetHandle() const
{
switch (eventType) {
case GEN_PURPOSE: return handle;
case TIMED: return timerHandle;
default: return ioHandle;
}
}
/**
* Return the type of this event.
*/
EventType GetEventType() const { return eventType; }
/**
* Get the number of threads that are currently blocked waiting for this event
*
* @return The number of blocked threads
*/
uint32_t GetNumBlockedThreads() { return numThreads; }
private:
static void Init();
static void Shutdown();
friend class StaticGlobals;
HANDLE handle; /**< General purpose event handle */
HANDLE ioHandle; /**< I/O event handle */
EventType eventType; /**< Type of event */
uint32_t period; /**< Number of milliseconds between periodic timed events */
HANDLE timerHandle; /**< Waitable timer used to implement a TIMED event */
SocketFd ioFd; /**< Socket descriptor or INVALID_SOCKET_FD if not socket based IO */
int32_t numThreads; /**< Number of threads currently waiting on this event */
bool networkIfaceEvent;
HANDLE networkIfaceHandle;
bool isSocket; /**< Is this event for socket or named pipe */
/**
* Private copy constructor.
* Events cannot be safely copied because they contain events handles.
*/
Event& operator=(const Event&);
/**
* Helper method used to calculate mask for WSAEventSelect
* @param evt Event being waited on.
*/
static void SetIOMask(Event& evt);
/**
* Helper method used to release mask for WSAEventSelect.
* @param evt Event previously referenced in SetIOMask().
*/
static void ReleaseIOMask(Event& evt);
/**
* Increment the count of threads blocked on this event
*/
void IncrementNumThreads() { IncrementAndFetch(&numThreads); }
/**
* Decrement the count of threads blocked on this event
*/
void DecrementNumThreads() { DecrementAndFetch(&numThreads); }
/**
* Event polling method used to check whether the event has been set.
*/
bool IsNetworkEventSet();
};
} /* namespace */
#endif
|