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
|
#pragma once
#include "ThreadData.h"
// Note: The implementation is in ThreadData.cpp.
namespace os {
/**
* OS thread.
*
* The Thread object represents a live instance of an OS thread. You can
* use the == operator to see if two threads are the same. The underlying OS
* thread will be kept running (even though it is not doing anything useful)
* as long as there are any Thread objects referring the thread.
*
* For windows:
* CoInitializeEx will be called for every thread created from this class. For
* other threads, please call initThread and cleanThread when before using the
* thread.
*/
class Thread {
public:
// Copy.
Thread(const Thread &o) : data(o.data) {
if (data)
data->addRef();
}
// Destroy.
~Thread() {
if (data)
data->release();
}
// Copy.
Thread &operator =(const Thread &o) {
if (this != &o) {
if (data)
data->release();
data = o.data;
if (data)
data->addRef();
}
return *this;
}
#ifdef USE_MOVE
// Move.
Thread(Thread &&o) : data(o.data) {
o.data = null;
}
Thread &operator =(Thread &&o) {
std::swap(data, o.data);
return *this;
}
#endif
// Compare.
inline bool operator ==(const Thread &o) const { return data == o.data; }
inline bool operator !=(const Thread &o) const { return !(*this == o); }
// Get the thread data.
inline ThreadData *threadData() const { return data; }
// Get an unique identifier for this thread.
inline uintptr_t id() const { return (uintptr_t)data; }
// Attach a os handle to this thread.
void attach(Handle h) const;
// Detach an os handle from this thread. This should be done before the handle is closed.
// Note: Currently only applicable on POSIX systems.
void detach(Handle h) const;
// Get a list of UThreads running on this thread. Note that access to this list is not thread safe.
const InlineSet<Stack> &stacks() const;
// Get all idle threads. In contrast to 'stacks', acquires the appropriate lock before accessing 'stacks'.
vector<UThread> idleUThreads();
// Start a thread.
static Thread spawn(ThreadGroup &group);
static Thread spawn(const util::Fn<void, void> &start, ThreadGroup &group);
// Start a thread with a specific 'ThreadWait' behaviour. Will take ownership of 'wait'.
static Thread spawn(ThreadWait *wait, ThreadGroup &group);
// Get the current thread.
static Thread current();
// Set the stack base for the first thread.
static void setStackBase(void *base);
// Invalid thread.
static const Thread invalid;
// Initialize a thread with any OS specific resources.
static void initThread();
static void cleanThread();
friend wostream &operator <<(wostream &to, const Thread &o);
private:
friend class ThreadGroupData;
// Create.
explicit Thread(ThreadData *data);
// Thread data.
ThreadData *data;
};
wostream &operator <<(wostream &to, const Thread &o);
}
|