blob: b6ce54964743fd97e10c6be8ea27338cd376f9a4 (
plain)
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
|
// **********************************************************************
//
// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
//
// This copy of Ice is licensed to you under the terms described in the
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************
#ifndef ICE_UTIL_THREAD_H
#define ICE_UTIL_THREAD_H
#include <IceUtil/Shared.h>
#include <IceUtil/Handle.h>
#include <IceUtil/Mutex.h>
namespace IceUtil
{
class Time;
#ifdef _WIN32
struct HandleWrapper : public Shared
{
// Inline for performance reasons.
HandleWrapper(HANDLE h) :
handle(h)
{
}
// Inline for performance reasons.
virtual ~HandleWrapper()
{
if(handle)
{
CloseHandle(handle);
}
}
HANDLE handle;
};
typedef Handle<HandleWrapper> HandleWrapperPtr;
#endif
#ifdef _WIN32
typedef unsigned int ThreadId;
#else
typedef pthread_t ThreadId;
#endif
class ICE_UTIL_API ThreadControl
{
public:
ThreadControl();
#ifdef _WIN32
ThreadControl(const HandleWrapperPtr&, ThreadId);
#else
ThreadControl(ThreadId);
#endif
ThreadControl(const ThreadControl&);
ThreadControl& operator=(const ThreadControl&);
bool operator==(const ThreadControl&) const;
bool operator!=(const ThreadControl&) const;
bool operator<(const ThreadControl&) const;
//
// Return the ID of the thread underlying this ThreadControl.
//
ThreadId id() const;
//
// Wait until the controlled thread terminates. The call has POSIX
// semantics.
//
// At most one thread can wait for the termination of a given
// thread. Calling join on a thread on which another thread is
// already waiting for termination results in undefined behaviour,
// as does joining with a thread after having joined with it
// previously, or joining with a detached thread.
//
void join();
//
// Detach a thread. Once a thread is detached, it cannot be
// detached again, nor can it be joined with. Every thread that
// was created using the IceUtil::Thread class must either be
// joined with or detached exactly once. Detaching a thread a
// second time, or detaching a thread that was previously joined
// with results in undefined behavior.
//
void detach();
//
// Check whether a thread is still alive. This is useful to implement
// a non-blocking join().
//
bool isAlive() const;
static void sleep(const Time&);
static void yield();
private:
Mutex _stateMutex;
#ifdef _WIN32
HandleWrapperPtr _handle;
#endif
ThreadId _id;
};
class ICE_UTIL_API Thread : virtual public IceUtil::Shared
{
public:
Thread();
virtual ~Thread();
ThreadId id() const;
virtual void run() = 0;
ThreadControl start(size_t = 0);
ThreadControl getThreadControl() const;
bool operator==(const Thread&) const;
bool operator!=(const Thread&) const;
bool operator<(const Thread&) const;
Thread(const Thread&); // Copying is forbidden
void operator=(const Thread&); // Assignment is forbidden
private:
Mutex _stateMutex;
bool _started;
#ifdef _WIN32
HandleWrapperPtr _handle;
#endif
ThreadId _id;
};
typedef Handle<Thread> ThreadPtr;
}
#endif
|