summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2018-04-05 21:29:53 -0700
committerThiago Macieira <thiago.macieira@intel.com>2018-04-06 22:46:49 +0000
commita9d903d18f668a6827149f82816caf96ac6365a2 (patch)
treed4e5e1d5fff7e2d12546ed302625d0821d251acd /src
parent28c9ad199c313444149471e854bfa6cc7c708549 (diff)
QSemaphore: Fix 64-bit Linux QSemaphores initialized to non-zero
The original design for the 64-bit futex had the token count replicated in the high part. But the constructor wasn't setting it. This is one of the issues I had noticed when investigating QTBUG-66875, but didn't need to address since the the fix I ended up applying in commit 081c001deb75fa38385d3ff8cbbdb4f788529133 made that unnecessary: the high part only had the number of waiters. Unfortunately, when commit f502270c0f06daba75c1da381bd1658d81aa7bba brought back the token count in the high part, I failed to correct that problem. As a consequence, every QSemaphore that was initialized in the constructor to a non-zero value would eventually deadlock. This commit fixes that oversight. Task-number: QTBUG-67481 Change-Id: I662b8f168c74440ab1a8fffd1522be6b85adb4d0 Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io> Reviewed-by: Svenn-Arne Dragly <svenn-arne.dragly@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/thread/qsemaphore.cpp10
1 files changed, 7 insertions, 3 deletions
diff --git a/src/corelib/thread/qsemaphore.cpp b/src/corelib/thread/qsemaphore.cpp
index c440d6db39..e91e859975 100644
--- a/src/corelib/thread/qsemaphore.cpp
+++ b/src/corelib/thread/qsemaphore.cpp
@@ -291,10 +291,14 @@ public:
QSemaphore::QSemaphore(int n)
{
Q_ASSERT_X(n >= 0, "QSemaphore", "parameter 'n' must be non-negative");
- if (futexAvailable())
- u.store(n);
- else
+ if (futexAvailable()) {
+ quintptr nn = unsigned(n);
+ if (futexHasWaiterCount)
+ nn |= quint64(nn) << 32; // token count replicated in high word
+ u.store(nn);
+ } else {
d = new QSemaphorePrivate(n);
+ }
}
/*!