thread/qwaitcondition_unix.cpp

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/**************************************************************************** -
2** -
3** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -
4** Contact: http://www.qt-project.org/legal -
5** -
6** This file is part of the QtCore module of the Qt Toolkit. -
7** -
8** $QT_BEGIN_LICENSE:LGPL$ -
9** Commercial License Usage -
10** Licensees holding valid commercial Qt licenses may use this file in -
11** accordance with the commercial license agreement provided with the -
12** Software or, alternatively, in accordance with the terms contained in -
13** a written agreement between you and Digia. For licensing terms and -
14** conditions see http://qt.digia.com/licensing. For further information -
15** use the contact form at http://qt.digia.com/contact-us. -
16** -
17** GNU Lesser General Public License Usage -
18** Alternatively, this file may be used under the terms of the GNU Lesser -
19** General Public License version 2.1 as published by the Free Software -
20** Foundation and appearing in the file LICENSE.LGPL included in the -
21** packaging of this file. Please review the following information to -
22** ensure the GNU Lesser General Public License version 2.1 requirements -
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -
24** -
25** In addition, as a special exception, Digia gives you certain additional -
26** rights. These rights are described in the Digia Qt LGPL Exception -
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -
28** -
29** GNU General Public License Usage -
30** Alternatively, this file may be used under the terms of the GNU -
31** General Public License version 3.0 as published by the Free Software -
32** Foundation and appearing in the file LICENSE.GPL included in the -
33** packaging of this file. Please review the following information to -
34** ensure the GNU General Public License version 3.0 requirements will be -
35** met: http://www.gnu.org/copyleft/gpl.html. -
36** -
37** -
38** $QT_END_LICENSE$ -
39** -
40****************************************************************************/ -
41 -
42#include "qplatformdefs.h" -
43#include "qwaitcondition.h" -
44#include "qmutex.h" -
45#include "qreadwritelock.h" -
46#include "qatomic.h" -
47#include "qstring.h" -
48 -
49#include "qmutex_p.h" -
50#include "qreadwritelock_p.h" -
51 -
52#include <errno.h> -
53 -
54#ifndef QT_NO_THREAD -
55 -
56QT_BEGIN_NAMESPACE -
57 -
58static void report_error(int code, const char *where, const char *what) -
59{ -
60 if (code != 0)
partially evaluated: code != 0
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:101767059
0-101767059
61 qWarning("%s: %s failure: %s", where, what, qPrintable(qt_error_string(code)));
never executed: QMessageLogger("thread/qwaitcondition_unix.cpp", 61, __PRETTY_FUNCTION__).warning("%s: %s failure: %s", where, what, QString(qt_error_string(code)).toLocal8Bit().constData());
0
62}
executed: }
Execution Count:101744265
101744265
63 -
64class QWaitConditionPrivate { -
65public: -
66 pthread_mutex_t mutex; -
67 pthread_cond_t cond; -
68 int waiters; -
69 int wakeups; -
70 -
71 bool wait(unsigned long time) -
72 { -
73 int code;
executed (the execution status of this line is deduced): int code;
-
74 forever {
executed (the execution status of this line is deduced): for(;;) {
-
75 if (time != ULONG_MAX) {
evaluated: time != (9223372036854775807L * 2UL + 1UL)
TRUEFALSE
yes
Evaluation Count:7137652
yes
Evaluation Count:2927835
2927835-7137652
76 struct timeval tv;
executed (the execution status of this line is deduced): struct timeval tv;
-
77 gettimeofday(&tv, 0);
executed (the execution status of this line is deduced): gettimeofday(&tv, 0);
-
78 -
79 timespec ti;
executed (the execution status of this line is deduced): timespec ti;
-
80 ti.tv_nsec = (tv.tv_usec + (time % 1000) * 1000) * 1000;
executed (the execution status of this line is deduced): ti.tv_nsec = (tv.tv_usec + (time % 1000) * 1000) * 1000;
-
81 ti.tv_sec = tv.tv_sec + (time / 1000) + (ti.tv_nsec / 1000000000);
executed (the execution status of this line is deduced): ti.tv_sec = tv.tv_sec + (time / 1000) + (ti.tv_nsec / 1000000000);
-
82 ti.tv_nsec %= 1000000000;
executed (the execution status of this line is deduced): ti.tv_nsec %= 1000000000;
-
83 -
84 code = pthread_cond_timedwait(&cond, &mutex, &ti);
executed (the execution status of this line is deduced): code = pthread_cond_timedwait(&cond, &mutex, &ti);
-
85 } else {
executed: }
Execution Count:7137660
7137660
86 code = pthread_cond_wait(&cond, &mutex);
executed (the execution status of this line is deduced): code = pthread_cond_wait(&cond, &mutex);
-
87 }
executed: }
Execution Count:2927835
2927835
88 if (code == 0 && wakeups == 0) {
evaluated: code == 0
TRUEFALSE
yes
Evaluation Count:10065156
yes
Evaluation Count:316
partially evaluated: wakeups == 0
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:10065167
0-10065167
89 // many vendors warn of spurios wakeups from -
90 // pthread_cond_wait(), especially after signal delivery, -
91 // even though POSIX doesn't allow for it... sigh -
92 continue;
never executed: continue;
0
93 } -
94 break;
executed: break;
Execution Count:10065487
10065487
95 } -
96 -
97 Q_ASSERT_X(waiters > 0, "QWaitCondition::wait", "internal error (waiters)");
executed (the execution status of this line is deduced): qt_noop();
-
98 --waiters;
executed (the execution status of this line is deduced): --waiters;
-
99 if (code == 0) {
evaluated: code == 0
TRUEFALSE
yes
Evaluation Count:10065165
yes
Evaluation Count:316
316-10065165
100 Q_ASSERT_X(wakeups > 0, "QWaitCondition::wait", "internal error (wakeups)");
executed (the execution status of this line is deduced): qt_noop();
-
101 --wakeups;
executed (the execution status of this line is deduced): --wakeups;
-
102 }
executed: }
Execution Count:10065162
10065162
103 report_error(pthread_mutex_unlock(&mutex), "QWaitCondition::wait()", "mutex unlock");
executed (the execution status of this line is deduced): report_error(pthread_mutex_unlock(&mutex), "QWaitCondition::wait()", "mutex unlock");
-
104 -
105 if (code && code != ETIMEDOUT)
evaluated: code
TRUEFALSE
yes
Evaluation Count:316
yes
Evaluation Count:10064389
partially evaluated: code != 110
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:316
0-10064389
106 report_error(code, "QWaitCondition::wait()", "cv wait");
never executed: report_error(code, "QWaitCondition::wait()", "cv wait");
0
107 -
108 return (code == 0);
executed: return (code == 0);
Execution Count:10064794
10064794
109 } -
110}; -
111 -
112 -
113QWaitCondition::QWaitCondition() -
114{ -
115 d = new QWaitConditionPrivate;
executed (the execution status of this line is deduced): d = new QWaitConditionPrivate;
-
116 report_error(pthread_mutex_init(&d->mutex, NULL), "QWaitCondition", "mutex init");
executed (the execution status of this line is deduced): report_error(pthread_mutex_init(&d->mutex, __null), "QWaitCondition", "mutex init");
-
117 report_error(pthread_cond_init(&d->cond, NULL), "QWaitCondition", "cv init");
executed (the execution status of this line is deduced): report_error(pthread_cond_init(&d->cond, __null), "QWaitCondition", "cv init");
-
118 d->waiters = d->wakeups = 0;
executed (the execution status of this line is deduced): d->waiters = d->wakeups = 0;
-
119}
executed: }
Execution Count:5128791
5128791
120 -
121 -
122QWaitCondition::~QWaitCondition() -
123{ -
124 report_error(pthread_cond_destroy(&d->cond), "QWaitCondition", "cv destroy");
executed (the execution status of this line is deduced): report_error(pthread_cond_destroy(&d->cond), "QWaitCondition", "cv destroy");
-
125 report_error(pthread_mutex_destroy(&d->mutex), "QWaitCondition", "mutex destroy");
executed (the execution status of this line is deduced): report_error(pthread_mutex_destroy(&d->mutex), "QWaitCondition", "mutex destroy");
-
126 delete d;
executed (the execution status of this line is deduced): delete d;
-
127}
executed: }
Execution Count:5141844
5141844
128 -
129void QWaitCondition::wakeOne() -
130{ -
131 report_error(pthread_mutex_lock(&d->mutex), "QWaitCondition::wakeOne()", "mutex lock");
executed (the execution status of this line is deduced): report_error(pthread_mutex_lock(&d->mutex), "QWaitCondition::wakeOne()", "mutex lock");
-
132 d->wakeups = qMin(d->wakeups + 1, d->waiters);
executed (the execution status of this line is deduced): d->wakeups = qMin(d->wakeups + 1, d->waiters);
-
133 report_error(pthread_cond_signal(&d->cond), "QWaitCondition::wakeOne()", "cv signal");
executed (the execution status of this line is deduced): report_error(pthread_cond_signal(&d->cond), "QWaitCondition::wakeOne()", "cv signal");
-
134 report_error(pthread_mutex_unlock(&d->mutex), "QWaitCondition::wakeOne()", "mutex unlock");
executed (the execution status of this line is deduced): report_error(pthread_mutex_unlock(&d->mutex), "QWaitCondition::wakeOne()", "mutex unlock");
-
135}
executed: }
Execution Count:6009952
6009952
136 -
137void QWaitCondition::wakeAll() -
138{ -
139 report_error(pthread_mutex_lock(&d->mutex), "QWaitCondition::wakeAll()", "mutex lock");
executed (the execution status of this line is deduced): report_error(pthread_mutex_lock(&d->mutex), "QWaitCondition::wakeAll()", "mutex lock");
-
140 d->wakeups = d->waiters;
executed (the execution status of this line is deduced): d->wakeups = d->waiters;
-
141 report_error(pthread_cond_broadcast(&d->cond), "QWaitCondition::wakeAll()", "cv broadcast");
executed (the execution status of this line is deduced): report_error(pthread_cond_broadcast(&d->cond), "QWaitCondition::wakeAll()", "cv broadcast");
-
142 report_error(pthread_mutex_unlock(&d->mutex), "QWaitCondition::wakeAll()", "mutex unlock");
executed (the execution status of this line is deduced): report_error(pthread_mutex_unlock(&d->mutex), "QWaitCondition::wakeAll()", "mutex unlock");
-
143}
executed: }
Execution Count:14492127
14492127
144 -
145bool QWaitCondition::wait(QMutex *mutex, unsigned long time) -
146{ -
147 if (! mutex)
partially evaluated: ! mutex
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:10065198
0-10065198
148 return false;
never executed: return false;
0
149 if (mutex->isRecursive()) {
partially evaluated: mutex->isRecursive()
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:10065198
0-10065198
150 qWarning("QWaitCondition: cannot wait on recursive mutexes");
never executed (the execution status of this line is deduced): QMessageLogger("thread/qwaitcondition_unix.cpp", 150, __PRETTY_FUNCTION__).warning("QWaitCondition: cannot wait on recursive mutexes");
-
151 return false;
never executed: return false;
0
152 } -
153 -
154 report_error(pthread_mutex_lock(&d->mutex), "QWaitCondition::wait()", "mutex lock");
executed (the execution status of this line is deduced): report_error(pthread_mutex_lock(&d->mutex), "QWaitCondition::wait()", "mutex lock");
-
155 ++d->waiters;
executed (the execution status of this line is deduced): ++d->waiters;
-
156 mutex->unlock();
executed (the execution status of this line is deduced): mutex->unlock();
-
157 -
158 bool returnValue = d->wait(time);
executed (the execution status of this line is deduced): bool returnValue = d->wait(time);
-
159 -
160 mutex->lock();
executed (the execution status of this line is deduced): mutex->lock();
-
161 -
162 return returnValue;
executed: return returnValue;
Execution Count:10065213
10065213
163} -
164 -
165bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time) -
166{ -
167 if (!readWriteLock || readWriteLock->d->accessCount == 0)
partially evaluated: !readWriteLock
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:273
partially evaluated: readWriteLock->d->accessCount == 0
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:273
0-273
168 return false;
never executed: return false;
0
169 if (readWriteLock->d->accessCount < -1) {
partially evaluated: readWriteLock->d->accessCount < -1
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:273
0-273
170 qWarning("QWaitCondition: cannot wait on QReadWriteLocks with recursive lockForWrite()");
never executed (the execution status of this line is deduced): QMessageLogger("thread/qwaitcondition_unix.cpp", 170, __PRETTY_FUNCTION__).warning("QWaitCondition: cannot wait on QReadWriteLocks with recursive lockForWrite()");
-
171 return false;
never executed: return false;
0
172 } -
173 -
174 report_error(pthread_mutex_lock(&d->mutex), "QWaitCondition::wait()", "mutex lock");
executed (the execution status of this line is deduced): report_error(pthread_mutex_lock(&d->mutex), "QWaitCondition::wait()", "mutex lock");
-
175 ++d->waiters;
executed (the execution status of this line is deduced): ++d->waiters;
-
176 -
177 int previousAccessCount = readWriteLock->d->accessCount;
executed (the execution status of this line is deduced): int previousAccessCount = readWriteLock->d->accessCount;
-
178 readWriteLock->unlock();
executed (the execution status of this line is deduced): readWriteLock->unlock();
-
179 -
180 bool returnValue = d->wait(time);
executed (the execution status of this line is deduced): bool returnValue = d->wait(time);
-
181 -
182 if (previousAccessCount < 0)
evaluated: previousAccessCount < 0
TRUEFALSE
yes
Evaluation Count:231
yes
Evaluation Count:42
42-231
183 readWriteLock->lockForWrite();
executed: readWriteLock->lockForWrite();
Execution Count:231
231
184 else -
185 readWriteLock->lockForRead();
executed: readWriteLock->lockForRead();
Execution Count:42
42
186 -
187 return returnValue;
executed: return returnValue;
Execution Count:273
273
188} -
189 -
190QT_END_NAMESPACE -
191 -
192#endif // QT_NO_THREAD -
193 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial