Diffstat (limited to 'qmake/tools/qwaitcondition_unix.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | qmake/tools/qwaitcondition_unix.cpp | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/qmake/tools/qwaitcondition_unix.cpp b/qmake/tools/qwaitcondition_unix.cpp index 99c1014..6684617 100644 --- a/qmake/tools/qwaitcondition_unix.cpp +++ b/qmake/tools/qwaitcondition_unix.cpp | |||
@@ -79,97 +79,97 @@ struct QWaitConditionPrivate { | |||
79 | // Key was pressed, do something interesting | 79 | // Key was pressed, do something interesting |
80 | do_something(); | 80 | do_something(); |
81 | } | 81 | } |
82 | \endcode | 82 | \endcode |
83 | 83 | ||
84 | A fourth thread would read key presses and wake the other three | 84 | A fourth thread would read key presses and wake the other three |
85 | threads up every time it receives one, like this: | 85 | threads up every time it receives one, like this: |
86 | 86 | ||
87 | \code | 87 | \code |
88 | QWaitCondition key_pressed; | 88 | QWaitCondition key_pressed; |
89 | 89 | ||
90 | for (;;) { | 90 | for (;;) { |
91 | getchar(); | 91 | getchar(); |
92 | // Causes any thread in key_pressed.wait() to return from | 92 | // Causes any thread in key_pressed.wait() to return from |
93 | // that method and continue processing | 93 | // that method and continue processing |
94 | key_pressed.wakeAll(); | 94 | key_pressed.wakeAll(); |
95 | } | 95 | } |
96 | \endcode | 96 | \endcode |
97 | 97 | ||
98 | Note that the order the three threads are woken up in is | 98 | Note that the order the three threads are woken up in is |
99 | undefined, and that if some or all of the threads are still in | 99 | undefined, and that if some or all of the threads are still in |
100 | do_something() when the key is pressed, they won't be woken up | 100 | do_something() when the key is pressed, they won't be woken up |
101 | (since they're not waiting on the condition variable) and so the | 101 | (since they're not waiting on the condition variable) and so the |
102 | task will not be performed for that key press. This can be | 102 | task will not be performed for that key press. This can be |
103 | avoided by, for example, doing something like this: | 103 | avoided by, for example, doing something like this: |
104 | 104 | ||
105 | \code | 105 | \code |
106 | QMutex mymutex; | 106 | QMutex mymutex; |
107 | QWaitCondition key_pressed; | 107 | QWaitCondition key_pressed; |
108 | int mycount=0; | 108 | int mycount=0; |
109 | 109 | ||
110 | // Worker thread code | 110 | // Worker thread code |
111 | for (;;) { | 111 | for (;;) { |
112 | key_pressed.wait(); // This is a QWaitCondition global variable | 112 | key_pressed.wait(); // This is a QWaitCondition global variable |
113 | mymutex.lock(); | 113 | mymutex.lock(); |
114 | mycount++; | 114 | mycount++; |
115 | mymutex.unlock(); | 115 | mymutex.unlock(); |
116 | do_something(); | 116 | do_something(); |
117 | mymutex.lock(); | 117 | mymutex.lock(); |
118 | mycount--; | 118 | mycount--; |
119 | mymutex.unlock(); | 119 | mymutex.unlock(); |
120 | } | 120 | } |
121 | 121 | ||
122 | // Key reading thread code | 122 | // Key reading thread code |
123 | for (;;) { | 123 | for (;;) { |
124 | getchar(); | 124 | getchar(); |
125 | mymutex.lock(); | 125 | mymutex.lock(); |
126 | // Sleep until there are no busy worker threads | 126 | // Sleep until there are no busy worker threads |
127 | while( count > 0 ) { | 127 | while( mycount > 0 ) { |
128 | mymutex.unlock(); | 128 | mymutex.unlock(); |
129 | sleep( 1 ); | 129 | sleep( 1 ); |
130 | mymutex.lock(); | 130 | mymutex.lock(); |
131 | } | 131 | } |
132 | mymutex.unlock(); | 132 | mymutex.unlock(); |
133 | key_pressed.wakeAll(); | 133 | key_pressed.wakeAll(); |
134 | } | 134 | } |
135 | \endcode | 135 | \endcode |
136 | 136 | ||
137 | The mutexes are necessary because the results of two threads | 137 | The mutexes are necessary because the results of two threads |
138 | attempting to change the value of the same variable simultaneously | 138 | attempting to change the value of the same variable simultaneously |
139 | are unpredictable. | 139 | are unpredictable. |
140 | */ | 140 | */ |
141 | 141 | ||
142 | /*! | 142 | /*! |
143 | Constructs a new event signalling, i.e. wait condition, object. | 143 | Constructs a new event signalling, i.e. wait condition, object. |
144 | */ | 144 | */ |
145 | QWaitCondition::QWaitCondition() | 145 | QWaitCondition::QWaitCondition() |
146 | { | 146 | { |
147 | d = new QWaitConditionPrivate; | 147 | d = new QWaitConditionPrivate; |
148 | 148 | ||
149 | int ret = pthread_cond_init(&d->cond, NULL); | 149 | int ret = pthread_cond_init(&d->cond, NULL); |
150 | 150 | ||
151 | #ifdef QT_CHECK_RANGE | 151 | #ifdef QT_CHECK_RANGE |
152 | if (ret) | 152 | if (ret) |
153 | qWarning( "Wait condition init failure: %s", strerror( ret ) ); | 153 | qWarning( "Wait condition init failure: %s", strerror( ret ) ); |
154 | #endif | 154 | #endif |
155 | } | 155 | } |
156 | 156 | ||
157 | 157 | ||
158 | /*! | 158 | /*! |
159 | Deletes the event signalling, i.e. wait condition, object. | 159 | Deletes the event signalling, i.e. wait condition, object. |
160 | */ | 160 | */ |
161 | QWaitCondition::~QWaitCondition() | 161 | QWaitCondition::~QWaitCondition() |
162 | { | 162 | { |
163 | int ret = pthread_cond_destroy(&d->cond); | 163 | int ret = pthread_cond_destroy(&d->cond); |
164 | 164 | ||
165 | if (ret) { | 165 | if (ret) { |
166 | #ifdef QT_CHECK_RANGE | 166 | #ifdef QT_CHECK_RANGE |
167 | qWarning( "Wait condition destroy failure: %s", strerror( ret ) ); | 167 | qWarning( "Wait condition destroy failure: %s", strerror( ret ) ); |
168 | #endif | 168 | #endif |
169 | 169 | ||
170 | // seems we have threads waiting on us, lets wake them up | 170 | // seems we have threads waiting on us, lets wake them up |
171 | pthread_cond_broadcast(&d->cond); | 171 | pthread_cond_broadcast(&d->cond); |
172 | } | 172 | } |
173 | 173 | ||
174 | delete d; | 174 | delete d; |
175 | } | 175 | } |
@@ -179,132 +179,137 @@ QWaitCondition::~QWaitCondition() | |||
179 | that is woken up depends on the operating system's scheduling | 179 | that is woken up depends on the operating system's scheduling |
180 | policies, and cannot be controlled or predicted. | 180 | policies, and cannot be controlled or predicted. |
181 | 181 | ||
182 | \sa wakeAll() | 182 | \sa wakeAll() |
183 | */ | 183 | */ |
184 | void QWaitCondition::wakeOne() | 184 | void QWaitCondition::wakeOne() |
185 | { | 185 | { |
186 | int ret = pthread_cond_signal(&d->cond); | 186 | int ret = pthread_cond_signal(&d->cond); |
187 | 187 | ||
188 | #ifdef QT_CHECK_RANGE | 188 | #ifdef QT_CHECK_RANGE |
189 | if (ret) | 189 | if (ret) |
190 | qWarning("Wait condition wakeOne failure: %s", strerror(ret)); | 190 | qWarning("Wait condition wakeOne failure: %s", strerror(ret)); |
191 | #endif | 191 | #endif |
192 | } | 192 | } |
193 | 193 | ||
194 | /*! | 194 | /*! |
195 | This wakes all threads waiting on the QWaitCondition. The order in | 195 | This wakes all threads waiting on the QWaitCondition. The order in |
196 | which the threads are woken up depends on the operating system's | 196 | which the threads are woken up depends on the operating system's |
197 | scheduling policies, and cannot be controlled or predicted. | 197 | scheduling policies, and cannot be controlled or predicted. |
198 | 198 | ||
199 | \sa wakeOne() | 199 | \sa wakeOne() |
200 | */ | 200 | */ |
201 | void QWaitCondition::wakeAll() | 201 | void QWaitCondition::wakeAll() |
202 | { | 202 | { |
203 | int ret = pthread_cond_broadcast(&d->cond); | 203 | int ret = pthread_cond_broadcast(&d->cond); |
204 | 204 | ||
205 | #ifdef QT_CHECK_RANGE | 205 | #ifdef QT_CHECK_RANGE |
206 | if (ret) | 206 | if (ret) |
207 | qWarning("Wait condition wakeAll failure: %s", strerror(ret)); | 207 | qWarning("Wait condition wakeAll failure: %s", strerror(ret)); |
208 | #endif | 208 | #endif |
209 | } | 209 | } |
210 | 210 | ||
211 | /*! | 211 | /*! |
212 | Wait on the thread event object. The thread calling this will | 212 | Wait on the thread event object. The thread calling this will |
213 | block until either of these conditions is met: | 213 | block until either of these conditions is met: |
214 | \list | 214 | \list |
215 | \i Another thread signals it using wakeOne() or wakeAll(). This | 215 | \i Another thread signals it using wakeOne() or wakeAll(). This |
216 | function will return TRUE in this case. | 216 | function will return TRUE in this case. |
217 | \i \a time milliseconds has elapsed. If \a time is ULONG_MAX (the | 217 | \i \a time milliseconds has elapsed. If \a time is ULONG_MAX (the |
218 | default), then the wait will never timeout (the event must be | 218 | default), then the wait will never timeout (the event must be |
219 | signalled). This function will return FALSE if the wait timed | 219 | signalled). This function will return FALSE if the wait timed |
220 | out. | 220 | out. |
221 | \endlist | 221 | \endlist |
222 | 222 | ||
223 | \sa wakeOne(), wakeAll() | 223 | \sa wakeOne(), wakeAll() |
224 | */ | 224 | */ |
225 | bool QWaitCondition::wait(unsigned long time) | 225 | bool QWaitCondition::wait(unsigned long time) |
226 | { | 226 | { |
227 | pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; | 227 | pthread_mutex_t mutex; |
228 | pthread_mutex_init( &mutex, 0 ); | ||
229 | pthread_mutex_lock( &mutex ); | ||
228 | 230 | ||
229 | int ret; | 231 | int ret; |
230 | if (time != ULONG_MAX) { | 232 | if (time != ULONG_MAX) { |
231 | struct timeval tv; | 233 | struct timeval tv; |
232 | gettimeofday(&tv, 0); | 234 | gettimeofday(&tv, 0); |
233 | 235 | ||
234 | timespec ti; | 236 | timespec ti; |
235 | ti.tv_nsec = (tv.tv_usec * 1000) + (time % 1000) * 1000; | 237 | ti.tv_nsec = ( tv.tv_usec + ( time % 1000 ) * 1000 ) * 1000; |
236 | ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 ); | 238 | ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 ); |
237 | ti.tv_nsec %= 1000000000; | 239 | ti.tv_nsec %= 1000000000; |
238 | 240 | ||
239 | ret = pthread_cond_timedwait(&d->cond, &mutex, &ti); | 241 | ret = pthread_cond_timedwait(&d->cond, &mutex, &ti); |
240 | } else | 242 | } else |
241 | ret = pthread_cond_wait(&d->cond, &mutex); | 243 | ret = pthread_cond_wait(&d->cond, &mutex); |
242 | 244 | ||
243 | #ifdef QT_CHECK_RANGE | 245 | #ifdef QT_CHECK_RANGE |
244 | if (ret && ret != ETIMEDOUT) | 246 | if (ret && ret != ETIMEDOUT) |
245 | qWarning("Wait condition wait failure: %s",strerror(ret)); | 247 | qWarning("Wait condition wait failure: %s",strerror(ret)); |
246 | #endif | 248 | #endif |
247 | 249 | ||
250 | pthread_mutex_unlock( &mutex ); | ||
251 | pthread_mutex_destroy( &mutex ); | ||
252 | |||
248 | return (ret == 0); | 253 | return (ret == 0); |
249 | } | 254 | } |
250 | 255 | ||
251 | /*! | 256 | /*! |
252 | \overload | 257 | \overload |
253 | 258 | ||
254 | Release the locked \a mutex and wait on the thread event object. | 259 | Release the locked \a mutex and wait on the thread event object. |
255 | The \a mutex must be initially locked by the calling thread. If \a | 260 | The \a mutex must be initially locked by the calling thread. If \a |
256 | mutex is not in a locked state, this function returns immediately. | 261 | mutex is not in a locked state, this function returns immediately. |
257 | If \a mutex is a recursive mutex, this function returns | 262 | If \a mutex is a recursive mutex, this function returns |
258 | immediately. The \a mutex will be unlocked, and the calling thread | 263 | immediately. The \a mutex will be unlocked, and the calling thread |
259 | will block until either of these conditions is met: | 264 | will block until either of these conditions is met: |
260 | \list | 265 | \list |
261 | \i Another thread signals it using wakeOne() or wakeAll(). This | 266 | \i Another thread signals it using wakeOne() or wakeAll(). This |
262 | function will return TRUE in this case. | 267 | function will return TRUE in this case. |
263 | \i \a time milliseconds has elapsed. If \a time is ULONG_MAX (the | 268 | \i \a time milliseconds has elapsed. If \a time is ULONG_MAX (the |
264 | default), then the wait will never timeout (the event must be | 269 | default), then the wait will never timeout (the event must be |
265 | signalled). This function will return FALSE if the wait timed | 270 | signalled). This function will return FALSE if the wait timed |
266 | out. | 271 | out. |
267 | \endlist | 272 | \endlist |
268 | 273 | ||
269 | The mutex will be returned to the same locked state. This function | 274 | The mutex will be returned to the same locked state. This function |
270 | is provided to allow the atomic transition from the locked state | 275 | is provided to allow the atomic transition from the locked state |
271 | to the wait state. | 276 | to the wait state. |
272 | 277 | ||
273 | \sa wakeOne(), wakeAll() | 278 | \sa wakeOne(), wakeAll() |
274 | */ | 279 | */ |
275 | bool QWaitCondition::wait(QMutex *mutex, unsigned long time) | 280 | bool QWaitCondition::wait(QMutex *mutex, unsigned long time) |
276 | { | 281 | { |
277 | if (! mutex) | 282 | if (! mutex) |
278 | return FALSE; | 283 | return FALSE; |
279 | 284 | ||
280 | if (mutex->d->type() == Q_MUTEX_RECURSIVE) { | 285 | if (mutex->d->type() == Q_MUTEX_RECURSIVE) { |
281 | #ifdef QT_CHECK_RANGE | 286 | #ifdef QT_CHECK_RANGE |
282 | qWarning("Wait condition warning: using recursive mutexes with\n" | 287 | qWarning("Wait condition warning: using recursive mutexes with\n" |
283 | " wait conditions is undefined!"); | 288 | " wait conditions is undefined!"); |
284 | #endif | 289 | #endif |
285 | return FALSE; | 290 | return FALSE; |
286 | } | 291 | } |
287 | 292 | ||
288 | int ret; | 293 | int ret; |
289 | if (time != ULONG_MAX) { | 294 | if (time != ULONG_MAX) { |
290 | struct timeval tv; | 295 | struct timeval tv; |
291 | gettimeofday(&tv, 0); | 296 | gettimeofday(&tv, 0); |
292 | 297 | ||
293 | timespec ti; | 298 | timespec ti; |
294 | ti.tv_nsec = (tv.tv_usec * 1000) + (time % 1000) * 1000; | 299 | ti.tv_nsec = ( tv.tv_usec + ( time % 1000 ) * 1000 ) * 1000; |
295 | ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 ); | 300 | ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 ); |
296 | ti.tv_nsec %= 1000000000; | 301 | ti.tv_nsec %= 1000000000; |
297 | 302 | ||
298 | ret = pthread_cond_timedwait(&d->cond, &mutex->d->handle, &ti); | 303 | ret = pthread_cond_timedwait(&d->cond, &mutex->d->handle, &ti); |
299 | } else | 304 | } else |
300 | ret = pthread_cond_wait(&d->cond, &mutex->d->handle); | 305 | ret = pthread_cond_wait(&d->cond, &mutex->d->handle); |
301 | 306 | ||
302 | #ifdef QT_CHECK_RANGE | 307 | #ifdef QT_CHECK_RANGE |
303 | if (ret && ret != ETIMEDOUT) | 308 | if (ret && ret != ETIMEDOUT) |
304 | qWarning("Wait condition wait failure: %s",strerror(ret)); | 309 | qWarning("Wait condition wait failure: %s",strerror(ret)); |
305 | #endif | 310 | #endif |
306 | 311 | ||
307 | return (ret == 0); | 312 | return (ret == 0); |
308 | } | 313 | } |
309 | 314 | ||
310 | #endif // QT_THREAD_SUPPORT | 315 | #endif // QT_THREAD_SUPPORT |