Root/
Source at commit 1322 created 12 years 8 months ago. By meklort, Add doxygen to utils folder | |
---|---|
1 | /****************************************************************************␊ |
2 | **␊ |
3 | ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).␊ |
4 | ** Contact: Nokia Corporation (qt-info@nokia.com)␊ |
5 | **␊ |
6 | ** This file is part of the QtCore module of the Qt Toolkit.␊ |
7 | **␊ |
8 | ** $QT_BEGIN_LICENSE:LGPL$␊ |
9 | ** No Commercial Usage␊ |
10 | ** This file contains pre-release code and may not be distributed.␊ |
11 | ** You may use this file in accordance with the terms and conditions␊ |
12 | ** contained in the either Technology Preview License Agreement or the␊ |
13 | ** Beta Release License Agreement.␊ |
14 | **␊ |
15 | ** GNU Lesser General Public License Usage␊ |
16 | ** Alternatively, this file may be used under the terms of the GNU Lesser␊ |
17 | ** General Public License version 2.1 as published by the Free Software␊ |
18 | ** Foundation and appearing in the file LICENSE.LGPL included in the␊ |
19 | ** packaging of this file. Please review the following information to␊ |
20 | ** ensure the GNU Lesser General Public License version 2.1 requirements␊ |
21 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.␊ |
22 | **␊ |
23 | ** In addition, as a special exception, Nokia gives you certain␊ |
24 | ** additional rights. These rights are described in the Nokia Qt LGPL␊ |
25 | ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this␊ |
26 | ** package.␊ |
27 | **␊ |
28 | ** GNU General Public License Usage␊ |
29 | ** Alternatively, this file may be used under the terms of the GNU␊ |
30 | ** General Public License version 3.0 as published by the Free Software␊ |
31 | ** Foundation and appearing in the file LICENSE.GPL included in the␊ |
32 | ** packaging of this file. Please review the following information to␊ |
33 | ** ensure the GNU General Public License version 3.0 requirements will be␊ |
34 | ** met: http://www.gnu.org/copyleft/gpl.html.␊ |
35 | **␊ |
36 | ** If you are unsure which license is appropriate for your use, please␊ |
37 | ** contact the sales department at http://www.qtsoftware.com/contact.␊ |
38 | ** $QT_END_LICENSE$␊ |
39 | **␊ |
40 | ****************************************************************************/␊ |
41 | ␊ |
42 | #include "qwaitcondition.h"␊ |
43 | #include "qmutex.h"␊ |
44 | #include <pthread.h>␊ |
45 | ␊ |
46 | #define MIN(a,b) ((a)<(b)?(a):(b))␊ |
47 | ␊ |
48 | static void report_error(int code, const char *where, const char *what)␊ |
49 | {␊ |
50 | if (code != 0)␊ |
51 | qWarning("%s: %s failure: %d", where, what, code);␊ |
52 | }␊ |
53 | ␊ |
54 | struct QWaitConditionPrivate␊ |
55 | {␊ |
56 | pthread_mutex_t mutex;␊ |
57 | pthread_cond_t cond;␊ |
58 | int waiters;␊ |
59 | int wakeups;␊ |
60 | ␊ |
61 | void wait()␊ |
62 | {␊ |
63 | int code;␊ |
64 | for (;;)␊ |
65 | {␊ |
66 | code = pthread_cond_wait(&cond, &mutex);␊ |
67 | if (code == 0 && wakeups == 0) ␊ |
68 | {␊ |
69 | // many vendors warn of spurios wakeups from␊ |
70 | // pthread_cond_wait(), especially after signal delivery,␊ |
71 | // even though POSIX doesn't allow for it... sigh␊ |
72 | continue;␊ |
73 | }␊ |
74 | break;␊ |
75 | }␊ |
76 | ␊ |
77 | --waiters;␊ |
78 | if (code == 0)␊ |
79 | {␊ |
80 | --wakeups;␊ |
81 | }␊ |
82 | else␊ |
83 | {␊ |
84 | report_error(code, "QWaitCondition::wait()", "cv wait");␊ |
85 | }␊ |
86 | report_error(pthread_mutex_unlock(&mutex), "QWaitCondition::wait()", "mutex unlock");␊ |
87 | }␊ |
88 | };␊ |
89 | ␊ |
90 | ␊ |
91 | QWaitCondition::QWaitCondition()␊ |
92 | {␊ |
93 | d = new QWaitConditionPrivate;␊ |
94 | report_error(pthread_mutex_init(&d->mutex, NULL), "QWaitCondition", "mutex init");␊ |
95 | report_error(pthread_cond_init(&d->cond, NULL), "QWaitCondition", "cv init");␊ |
96 | d->waiters = d->wakeups = 0;␊ |
97 | }␊ |
98 | ␊ |
99 | ␊ |
100 | QWaitCondition::~QWaitCondition()␊ |
101 | {␊ |
102 | report_error(pthread_cond_destroy(&d->cond), "QWaitCondition", "cv destroy");␊ |
103 | report_error(pthread_mutex_destroy(&d->mutex), "QWaitCondition", "mutex destroy");␊ |
104 | delete d;␊ |
105 | }␊ |
106 | ␊ |
107 | void QWaitCondition::wakeOne()␊ |
108 | {␊ |
109 | report_error(pthread_mutex_lock(&d->mutex), "QWaitCondition::wakeOne()", "mutex lock");␊ |
110 | d->wakeups = MIN(d->wakeups + 1, d->waiters);␊ |
111 | report_error(pthread_cond_signal(&d->cond), "QWaitCondition::wakeOne()", "cv signal");␊ |
112 | report_error(pthread_mutex_unlock(&d->mutex), "QWaitCondition::wakeOne()", "mutex unlock");␊ |
113 | }␊ |
114 | ␊ |
115 | void QWaitCondition::wakeAll()␊ |
116 | {␊ |
117 | report_error(pthread_mutex_lock(&d->mutex), "QWaitCondition::wakeAll()", "mutex lock");␊ |
118 | d->wakeups = d->waiters;␊ |
119 | report_error(pthread_cond_broadcast(&d->cond), "QWaitCondition::wakeAll()", "cv broadcast");␊ |
120 | report_error(pthread_mutex_unlock(&d->mutex), "QWaitCondition::wakeAll()", "mutex unlock");␊ |
121 | }␊ |
122 | ␊ |
123 | void QWaitCondition::wait(QMutex *mutex)␊ |
124 | {␊ |
125 | if (!mutex) return;␊ |
126 | ␊ |
127 | report_error(pthread_mutex_lock(&d->mutex), "QWaitCondition::wait()", "mutex lock");␊ |
128 | ++d->waiters;␊ |
129 | mutex->unlock();␊ |
130 | d->wait();␊ |
131 | mutex->lock();␊ |
132 | }␊ |
133 | ␊ |
134 |