Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4973 | right-hear | 1 | // -*- c++ -*- |
2 | /* |
||
3 | * Copyright 1999 Karl Nelson |
||
4 | * |
||
5 | * This library is free software; you can redistribute it and/or |
||
6 | * modify it under the terms of the GNU Library General Public |
||
7 | * License as published by the Free Software Foundation; either |
||
8 | * version 2 of the License, or (at your option) any later version. |
||
9 | * |
||
10 | * This library is distributed in the hope that it will be useful, |
||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
13 | * Library General Public License for more details. |
||
14 | * |
||
15 | * You should have received a copy of the GNU Library General Public |
||
16 | * License along with this library; if not, write to the Free |
||
17 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
||
18 | */ |
||
19 | #ifndef SIGCXX_THREAD_H |
||
20 | #define SIGCXX_THREAD_H |
||
21 | #include |
||
22 | |||
23 | #ifdef SIGC_PTHREADS |
||
24 | |||
25 | #ifdef SIGC_THREAD_IMPL |
||
26 | #include |
||
27 | #else |
||
28 | #include |
||
29 | #endif |
||
30 | |||
31 | #ifdef SIGC_CXX_NAMESPACES |
||
32 | namespace SigC |
||
33 | { |
||
34 | namespace Threads |
||
35 | { |
||
36 | #else |
||
37 | #define Threads |
||
38 | #endif |
||
39 | |||
40 | #ifdef SIGC_THREAD_IMPL |
||
41 | #ifdef SIGC_PTHREAD_DCE |
||
42 | struct CondAttr { pthread_condattr_t impl_;}; |
||
43 | struct MutexAttr { pthread_mutexattr_t impl_;}; |
||
44 | struct ThreadAttr { pthread_attr_t impl_;}; |
||
45 | #else |
||
46 | struct CondAttr { pthread_condattr_t* impl_;}; |
||
47 | struct MutexAttr { pthread_mutexattr_t* impl_;}; |
||
48 | struct ThreadAttr { pthread_attr_t* impl_;}; |
||
49 | #endif |
||
50 | typedef pthread_mutex_t MutexImpl; |
||
51 | typedef pthread_cond_t CondImpl; |
||
52 | typedef pthread_key_t KeyImpl; |
||
53 | typedef pthread_t ThreadImpl; |
||
54 | #else |
||
55 | class CondAttr {unsigned char dummy[SIGC_PTHREAD_COND_ATTR];}; |
||
56 | class CondImpl {unsigned char dummy[SIGC_PTHREAD_COND_IMPL];}; |
||
57 | class MutexAttr {unsigned char dummy[SIGC_PTHREAD_MUTEX_ATTR];}; |
||
58 | class MutexImpl {unsigned char dummy[SIGC_PTHREAD_MUTEX_IMPL];}; |
||
59 | class ThreadAttr {unsigned char dummy[SIGC_PTHREAD_THREAD_ATTR];}; |
||
60 | class ThreadImpl {unsigned char dummy[SIGC_PTHREAD_THREAD_IMPL];}; |
||
61 | class KeyImpl {unsigned char dummy[SIGC_PTHREAD_KEY_IMPL];}; |
||
62 | #endif |
||
63 | |||
64 | // Mutual Exclusion |
||
65 | class Mutex |
||
66 | { |
||
67 | typedef MutexImpl Impl; |
||
68 | private: |
||
69 | Impl mutex_; |
||
70 | int destroy(); |
||
71 | |||
72 | public: |
||
73 | static MutexAttr Default; |
||
74 | #ifdef SIGC_THREAD_IMPL |
||
75 | operator Impl* () {return (Impl*)(&mutex_);} |
||
76 | #endif |
||
77 | |||
78 | Mutex(const MutexAttr attr=Default); |
||
79 | |||
80 | // (needs work) |
||
81 | ~Mutex(); |
||
82 | |||
83 | int lock(); |
||
84 | int trylock(); |
||
85 | int unlock(); |
||
86 | }; |
||
87 | |||
88 | // A lazy way to unlock at end of scope |
||
89 | struct MLock |
||
90 | { |
||
91 | Mutex &mutex_; |
||
92 | MLock(Mutex& mutex):mutex_(mutex) {mutex_.lock();} |
||
93 | ~MLock() {mutex_.unlock();} |
||
94 | }; |
||
95 | |||
96 | // Condition Variable |
||
97 | struct Condition |
||
98 | { |
||
99 | typedef CondImpl Impl; |
||
100 | private: |
||
101 | Impl cond_; |
||
102 | |||
103 | int destroy(); |
||
104 | public: |
||
105 | static CondAttr Default; |
||
106 | #ifdef SIGC_THREAD_IMPL |
||
107 | operator Impl* () {return (Impl*)(&cond_);} |
||
108 | #endif |
||
109 | |||
110 | Condition(const CondAttr &attr=Default); |
||
111 | ~Condition(); |
||
112 | |||
113 | // restarts exactly one thread hung on condition |
||
114 | int signal(); |
||
115 | |||
116 | // restarts all threads waiting on condition |
||
117 | int broadcast(); |
||
118 | |||
119 | // unlocks a mutex while waiting on a condition, then reaquires lock. |
||
120 | int wait(Mutex &m); |
||
121 | |||
122 | // unlocks a mutex while waiting on a condition, then reaquires lock |
||
123 | // with a fixed maximum duration. |
||
124 | int wait(Mutex &m,struct timespec* spec); |
||
125 | |||
126 | }; |
||
127 | |||
128 | // Integer Semaphore |
||
129 | struct Semaphore |
||
130 | { |
||
131 | int value_; |
||
132 | Condition sig_; |
||
133 | Mutex access_; |
||
134 | |||
135 | void up(); |
||
136 | void down(); |
||
137 | |||
138 | Semaphore(int value=1); |
||
139 | ~Semaphore(); |
||
140 | }; |
||
141 | |||
142 | struct Private_ |
||
143 | { |
||
144 | KeyImpl key_; |
||
145 | void* get(); |
||
146 | void set(void *value); |
||
147 | void create(void (*dtor)(void*)); |
||
148 | void destroy(); |
||
149 | }; |
||
150 | |||
151 | // Private is a thread split static. |
||
152 | template |
||
153 | class Private : private Private_ |
||
154 | { |
||
155 | private: |
||
156 | static void dtor(void* v) |
||
157 | { |
||
158 | T* obj=(T*)v; |
||
159 | delete obj; |
||
160 | } |
||
161 | |||
162 | public: |
||
163 | |||
164 | T& operator =(const T& t) |
||
165 | {return (((T&)*this)=t);} |
||
166 | |||
167 | operator T& () |
||
168 | { |
||
169 | T *value=(T*)get(); |
||
170 | if (!value) |
||
171 | set((void*)(value=new T())); |
||
172 | return *(value); |
||
173 | } |
||
174 | |||
175 | Private() { create(&dtor); } |
||
176 | ~Private() { destroy(); } |
||
177 | }; |
||
178 | |||
179 | // int needs to initialized |
||
180 | template <> |
||
181 | class Private |
||
182 | { |
||
183 | private: |
||
184 | static void dtor(void* v) |
||
185 | { |
||
186 | int* obj=(int*)v; |
||
187 | delete obj; |
||
188 | } |
||
189 | |||
190 | public: |
||
191 | int& operator =(const int& t) |
||
192 | {return (((int&)*this)=t);} |
||
193 | |||
194 | operator int& () |
||
195 | { |
||
196 | int *value=(int*)get(); |
||
197 | if (!value) |
||
198 | set((void*)(value=new int(0))); |
||
199 | return *(value); |
||
200 | } |
||
201 | |||
202 | Private() { create(&dtor); } |
||
203 | ~Private() { destroy(); } |
||
204 | }; |
||
205 | |||
206 | struct Thread |
||
207 | { |
||
208 | protected: |
||
209 | typedef ThreadImpl Impl; |
||
210 | Impl thread_; |
||
211 | void* arg_; |
||
212 | ThreadAttr attr_; |
||
213 | |||
214 | static void* call_main_(void* obj); |
||
215 | |||
216 | public: |
||
217 | #ifdef SIGC_THREAD_IMPL |
||
218 | operator Impl* () {return &thread_;} |
||
219 | #endif |
||
220 | |||
221 | virtual void* main(void*)=0; |
||
222 | int detach(); |
||
223 | |||
224 | static ThreadAttr Default; |
||
225 | |||
226 | // arg is for passing extra data to main, but never pass a |
||
227 | // local variable or address of local variable. Arg must |
||
228 | // be available throughout life of program. |
||
229 | int start(void* arg=0); |
||
230 | |||
231 | Thread(const ThreadAttr &attr=Default); |
||
232 | virtual ~Thread(); |
||
233 | }; |
||
234 | |||
235 | |||
236 | #ifdef SIGC_CXX_NAMESPACES |
||
237 | } /* namespace Threads */ |
||
238 | } /* namespace SigC */ |
||
239 | #endif |
||
240 | |||
241 | #endif /* SIGC_PTHREADS */ |
||
242 | #endif /* SIGCXX_THREAD_H */> |