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
081c001deb 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>
This commit is contained in:
Thiago Macieira 2018-04-05 21:29:53 -07:00
parent 28c9ad199c
commit a9d903d18f

View File

@ -291,11 +291,15 @@ 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);
}
}
/*!
Destroys the semaphore.