/usr/include/x86_64-linux-gnu/qcc/Thread.h is in liballjoyn-common-dev-1509 15.09a-5.
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 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 | /**
* @file
*
* This file just wraps platform specific header files that define the thread
* abstraction interface.
*/
/******************************************************************************
* 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 _QCC_THREAD_H
#define _QCC_THREAD_H
#include <qcc/platform.h>
#include <qcc/String.h>
#include <qcc/Event.h>
#include <qcc/Mutex.h>
#include <Status.h>
#include <set>
#include <map>
#if defined(QCC_OS_GROUP_POSIX)
#include <qcc/posix/Thread.h>
#elif defined(QCC_OS_GROUP_WINDOWS)
#include <qcc/windows/Thread.h>
#else
#error No OS GROUP defined.
#endif
namespace qcc {
typedef void* ThreadReturn;
/**
* Put current thread to sleep for specified number of milliseconds.
*
* @param ms Number of milliseconds to sleep.
*/
QStatus Sleep(uint32_t ms);
/** @internal */
class Thread;
/**
* Callback interface used to notify of thread exit.
*/
class ThreadListener {
public:
/**
* Virtual destructor for derivable class.
*/
virtual ~ThreadListener() { }
/**
* Called when the thread is about to exit.
* The underlying Thread instance is guaranteed to not be accessed once
* this callback returns. This allows implementations to free the Thread
* if desired.
*
* @param thread Thread that has exited.
*/
virtual void ThreadExit(Thread* thread) = 0;
};
/**
* Abstract encapsulation of the os-specific threads.
*/
class Thread {
public:
/**
* Find the Thread for this thread (or NULL if no such thread).
*
* @return Thread for this thread. If current resource is
* not a Thread, NULL is returned.
*/
static Thread* GetThread();
/**
* Get the function name of this thread.
*
* @return The thread function name.
*/
static const char* GetThreadName();
/**
* Release and deallocate all threads that are marked as "external"
*/
static void CleanExternalThreads();
/**
* Function declaration for thread entry point
*
* @param arg Opaque argument passed to thread entry.
* @return Thread exit code
*/
typedef ThreadReturn (STDCALL * ThreadFunction)(void* arg);
/**
* Construct a new thread.
*
* @param funcName String representation of the function name (defaults to empty).
* @param func Entry point for new thread or NULL to use Run() as entry point.
* @param isExternal Create a "wrapper" Thread object for the calling thread rather
* than creating an actual thread.
*/
Thread(qcc::String funcName = "", ThreadFunction func = NULL, bool isExternal = false);
/**
* The destructor will kill the thread if it is running.
*/
virtual ~Thread(void);
/**
* Call Run() in its own thread with 'arg' as its argument.
* Passed in arguments that are pointers to memory must either
* have their ownership passed to Run, or must remain allocated
* for the duration of the thread. If the memory pointed to by
* 'arg' is to be accessed by more than one threading resource,
* then it must be protected through the use of Mutex's.<p>
*
* Subclasses that override this method should call the base class
* implementation of Start.
*
* @param arg The one and only parameter that 'func' will be called with
* (defaults to NULL).
* @param listener Listener to be informed of Thread events (defaults to NULL).
*
* @return Indication of whether creation of the thread succeeded or not.
*/
virtual QStatus Start(void* arg = NULL, ThreadListener* listener = NULL);
/**
* Stop the thread.
*
* This method sets the thread's isStopping state to true and set's the thread's stopped event
* to unblock any I/O. Stopping a thread using this method relies on the implementation of Run()
* (or threadfunc) to periodically check the state by calling IsStopping().<p>
*
* Subclasses that override this method should call the base class
* implementation of Stop.
*
* @return ER_OK if request was successful. This does not imply
* that Stop will successfully stop the thread.
*/
virtual QStatus Stop(void);
/**
* Alert a thread by causing any pending call to Event::Wait() to unblock
* This functionality is very similar to Stop(). The difference is that
* the thread is not required to cleanup and exit when this funciton is called.
* This version of Alert leaves the alertCode undisturbed.
*
* @return ER_OK if request was successful.
*/
virtual QStatus Alert(void);
/**
* Alert a thread by causing any pending call to Event::Wait() to unblock
* This functionality is very similar to Stop(). The difference is that
* the thread is not required to cleanup and exit when this funciton is called.
* This version of Alert sets the threads alertCode.
*
* @param alertCode Optional context that can be passed to the alerted thread.
* @return ER_OK if request was successful.
*/
virtual QStatus Alert(uint32_t alertCode);
/**
* This function allows one thread to wait for the completion of another
* thread. Once a thread has terminated, its exit value may be examined.
* A thread must not "join" itself.
*
* @return Indication of whether the join operation succeeded or not.
*/
virtual QStatus Join(void);
/**
* Indicate whether a stop has been requested for this thread.
*
* @return true iff thread has been signalled to stop.
*/
bool IsStopping(void) { return isStopping; }
/**
* Get the exit value. Any memory referenced by this pointer must either
* have been provided to the thread via its argument or allocated on the
* heap. Memory referencing any stack space from the recently exited
* thread is now invalid.
*
* @return The exit value encoded in a void *.
*/
ThreadReturn GetExitValue(void)
{
return exitValue;
}
/**
* Determine if the thread is currently running. A running thread can be stopped and joined.
*
* @return 'true' if the thread is running; 'false' otherwise.
*/
bool IsRunning(void) { return ((state == STARTED) || (state == RUNNING) || (state == STOPPING)); }
/**
* Get the name of the thread.
*
* @return A pointer to a C string of the thread name.
*/
const char* GetName(void) const { return funcName; }
/**
* Return underlying thread handle.
*
* @return Thread handle
*/
ThreadHandle GetHandle(void) { return handle; }
/**
* Get a reference to the stop er::Event object for use in er::Event::Wait().
*
* @return Reference to the stop er::Event.
*/
Event& GetStopEvent(void) { return stopEvent; }
/**
* Get the alertCode that was set by the caller to Alert()
*
* @return The alertCode specified by the caller to Alert.
*/
uint32_t GetAlertCode() const { return alertCode; }
/**
* Reset the alertCode that may have been set by a caller to Alert()
*/
void ResetAlertCode() { alertCode = 0; }
/**
* Add an aux ThreadListener.
* Aux ThreadListeners are called when the thread stops just like the primary ThreadListener
* (passed in Start). The difference is that aux ThreadListeners can NOT delete the Thread
* object where as the primary ThreadListener can. Also, there can be many aux ThreadListeners
* but only one primary ThreadListener.
*
* @param listener Aux ThreadListener to add.
*/
void AddAuxListener(ThreadListener* listener);
/**
* Remove an aux ThreadListener.
*
* @param listener Aux ThreadListener to add.
*/
void RemoveAuxListener(ThreadListener* listener);
protected:
Event stopEvent; ///< Event that indicates a stop request when set.
/**
* Invoked by the new thread if Start() returns successfully.
* The new thread exits when this method returns.
*
* The default version of Run() calls the thread function passed into
* the constructor. Override Run() the thread needs to be able
* to access Thread (or derrived class) members.
*
* @param arg Argument passed in via Start().
* @return Exit status for thread.
*/
virtual ThreadReturn STDCALL Run(void* arg);
private:
static QStatus Init();
static QStatus Shutdown();
friend class StaticGlobals;
/**
* Enumeration of thread states.
*/
enum {
INITIAL, /**< Initial thread state - no underlying OS thread */
STARTED, /**< Thread has started */
RUNNING, /**< Thread is running the thread function */
STOPPING, /**< Thread has completed the thread function and is cleaning up */
DEAD /**< Underlying OS thread is gone */
} state;
bool isStopping; ///< Thread has received a stop request
char funcName[80]; ///< Function name (used mostly in debug output).
ThreadFunction function; ///< Thread entry point or NULL is using Run() as entry point
ThreadHandle handle; ///< Thread handle.
ThreadReturn exitValue; ///< The returned 'value' from Run.
void* threadArg; ///< Run thread argument.
ThreadListener* threadListener; ///< Listener notified of thread events (or NULL).
bool isExternal; ///< If true, Thread is external (i.e. lifecycle not managed by Thread obj)
void* platformContext; ///< Context data specific to platform implementation
uint32_t alertCode; ///< Context passed from alerter to alertee
typedef std::set<ThreadListener*> ThreadListeners;
ThreadListeners auxListeners;
Mutex auxListenersLock;
#if defined(QCC_OS_GROUP_POSIX)
volatile int32_t waitCount;
Mutex waitLock;
bool hasBeenJoined;
qcc::Mutex hbjMutex;
#elif defined(QCC_OS_GROUP_WINDOWS)
ThreadId threadId; ///< Thread ID used by windows
#endif
/** Lock that protects global list of Threads and their handles */
static Mutex* threadListLock;
/** Thread list */
static std::map<ThreadId, Thread*>* threadList;
/** Called on thread exit to deallocate external Thread objects */
static void STDCALL CleanExternalThread(void* thread);
/**
* C callable thread entry point.
*
* @param thread Pointer to *this.
* @return Platform abstracted return type defined in \<os\>/Thread.h.
*/
static ThreadInternalReturn STDCALL RunInternal(void* thread);
/**
* Platform specific wrapper around the signal handler.
*
* @param signal Signal number received
*/
static void SigHandler(int signal);
};
}
#endif
|