summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThiago Macieira <[email protected]>2023-05-22 19:32:20 -0700
committerThiago Macieira <[email protected]>2025-06-30 07:23:56 -0700
commit6679efd2a4cc23de4ed947ef567a799d474e2079 (patch)
treef873fb493b518f68994705329b73bd4babb7a278
parent5bd58d67c14ac765a2a0abb7d5dbb499ac60f13b (diff)
Replace one-shot uses of QSemaphore with QLatch
This commit replaces one-shot synchronization of threads that were using QSemaphore with QLatch. QSemaphore is efficient on Linux and Windows, but allocates memory elsewhere. Even on those platforms where we have futex-like OS support, QSemaphore is heavier than what we really need here. All but one uses of QSemaphore in qtbase libraries (I didn't change examples or tests) were replaced. The remaining use of QSemaphore in qnetworkproxy_libproxy.cpp is a proper producer-consumer. Change-Id: Ib5ce7a497e034ebabb2cfffd1761a4fcb2be9a6c Reviewed-by: Volker Hilsheimer <[email protected]>
-rw-r--r--src/corelib/kernel/qmetaobject.cpp14
-rw-r--r--src/corelib/kernel/qobject.cpp26
-rw-r--r--src/corelib/kernel/qobject_p.h23
-rw-r--r--src/dbus/qdbusintegrator.cpp15
-rw-r--r--src/dbus/qdbusintegrator_p.h4
-rw-r--r--src/dbus/qdbusthreaddebug_p.h20
-rw-r--r--src/gui/image/qimage.cpp14
-rw-r--r--src/gui/image/qimage_conversions.cpp38
-rw-r--r--src/gui/painting/qdrawhelper.cpp8
-rw-r--r--src/gui/painting/qimagescale.cpp8
-rw-r--r--src/gui/painting/qimagescale_neon.cpp8
-rw-r--r--src/gui/painting/qimagescale_sse4.cpp8
-rw-r--r--src/network/kernel/qnetworkproxy_libproxy.cpp7
-rw-r--r--tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp10
14 files changed, 90 insertions, 113 deletions
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 795cc531114..b48922daeab 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -17,7 +17,7 @@
#include <qthread.h>
#include "private/qthread_p.h"
#if QT_CONFIG(thread)
-#include <qsemaphore.h>
+#include "private/qlatch_p.h"
#endif
// for normalizeTypeInternal
@@ -1748,9 +1748,9 @@ bool QMetaObject::invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase *
if (receiverInSameThread)
qWarning("QMetaObject::invokeMethod: Dead lock detected");
- QSemaphore semaphore;
- QCoreApplication::postEvent(object, new QMetaCallEvent(std::move(slot), nullptr, -1, argv, &semaphore));
- semaphore.acquire();
+ QLatch latch(1);
+ QCoreApplication::postEvent(object, new QMetaCallEvent(std::move(slot), nullptr, -1, argv, &latch));
+ latch.wait();
#endif // QT_CONFIG(thread)
} else {
qWarning("QMetaObject::invokeMethod: Unknown connection type");
@@ -2922,10 +2922,10 @@ auto QMetaMethodInvoker::invokeImpl(QMetaMethod self, void *target,
return InvokeFailReason::DeadLockDetected;
}
- QSemaphore semaphore;
+ QLatch latch(1);
QCoreApplication::postEvent(object, new QMetaCallEvent(idx_offset, idx_relative, callFunction,
- nullptr, -1, param, &semaphore));
- semaphore.acquire();
+ nullptr, -1, param, &latch));
+ latch.wait();
#endif // QT_CONFIG(thread)
}
return {};
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 38ded8117c0..888c71f5a49 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -27,7 +27,7 @@
#include <qscopeguard.h>
#include <qset.h>
#if QT_CONFIG(thread)
-#include <qsemaphore.h>
+#include <private/qlatch_p.h>
#endif
#include <private/qorderedmutexlocker_p.h>
@@ -476,8 +476,8 @@ void QObjectPrivate::reinitBindingStorageAfterThreadMove()
QAbstractMetaCallEvent::~QAbstractMetaCallEvent()
{
#if QT_CONFIG(thread)
- if (semaphore_)
- semaphore_->release();
+ if (latch)
+ latch->countDown();
#endif
}
@@ -506,8 +506,8 @@ inline void QMetaCallEvent::allocArgs()
QMetaCallEvent::QMetaCallEvent(ushort method_offset, ushort method_relative,
QObjectPrivate::StaticMetaCallFunction callFunction,
const QObject *sender, int signalId,
- void **args, QSemaphore *semaphore)
- : QAbstractMetaCallEvent(sender, signalId, semaphore),
+ void **args, QLatch *latch)
+ : QAbstractMetaCallEvent(sender, signalId, latch),
d({nullptr, args, callFunction, 0, method_offset, method_relative}),
prealloc_()
{
@@ -521,8 +521,8 @@ QMetaCallEvent::QMetaCallEvent(ushort method_offset, ushort method_relative,
*/
QMetaCallEvent::QMetaCallEvent(QtPrivate::QSlotObjectBase *slotO,
const QObject *sender, int signalId,
- void **args, QSemaphore *semaphore)
- : QAbstractMetaCallEvent(sender, signalId, semaphore),
+ void **args, QLatch *latch)
+ : QAbstractMetaCallEvent(sender, signalId, latch),
d({QtPrivate::SlotObjUniquePtr{slotO}, args, nullptr, 0, 0, ushort(-1)}),
prealloc_()
{
@@ -538,8 +538,8 @@ QMetaCallEvent::QMetaCallEvent(QtPrivate::QSlotObjectBase *slotO,
*/
QMetaCallEvent::QMetaCallEvent(QtPrivate::SlotObjUniquePtr slotO,
const QObject *sender, int signalId,
- void **args, QSemaphore *semaphore)
- : QAbstractMetaCallEvent(sender, signalId, semaphore),
+ void **args, QLatch *latch)
+ : QAbstractMetaCallEvent(sender, signalId, latch),
d{std::move(slotO), args, nullptr, 0, 0, ushort(-1)},
prealloc_()
{
@@ -4198,18 +4198,18 @@ void doActivate(QObject *sender, int signal_index, void **argv)
if (c->isSingleShot && !QObjectPrivate::removeConnection(c))
continue;
- QSemaphore semaphore;
+ QLatch latch(1);
{
QMutexLocker locker(signalSlotLock(receiver));
if (!c->isSingleShot && !c->receiver.loadAcquire())
continue;
QMetaCallEvent *ev = c->isSlotObject ?
- new QMetaCallEvent(c->slotObj, sender, signal_index, argv, &semaphore) :
+ new QMetaCallEvent(c->slotObj, sender, signal_index, argv, &latch) :
new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction,
- sender, signal_index, argv, &semaphore);
+ sender, signal_index, argv, &latch);
QCoreApplication::postEvent(receiver, ev);
}
- semaphore.acquire();
+ latch.wait();
continue;
#endif
}
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index 20c454506ab..dca9c1af932 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -328,16 +328,13 @@ bool QObjectPrivate::disconnect(const typename QtPrivate::FunctionPointer< Func1
&SignalType::Object::staticMetaObject);
}
-class QSemaphore;
+class QLatch;
class Q_CORE_EXPORT QAbstractMetaCallEvent : public QEvent
{
public:
- QAbstractMetaCallEvent(const QObject *sender, int signalId, QSemaphore *semaphore = nullptr)
- : QEvent(MetaCall), signalId_(signalId), sender_(sender)
-#if QT_CONFIG(thread)
- , semaphore_(semaphore)
-#endif
- { Q_UNUSED(semaphore); }
+ QAbstractMetaCallEvent(const QObject *sender, int signalId, QLatch *latch = nullptr)
+ : QEvent(MetaCall), signalId_(signalId), sender_(sender), latch(latch)
+ {}
~QAbstractMetaCallEvent();
virtual void placeMetaCall(QObject *object) = 0;
@@ -348,25 +345,23 @@ public:
private:
int signalId_;
const QObject *sender_;
-#if QT_CONFIG(thread)
- QSemaphore *semaphore_;
-#endif
+ QLatch *latch;
};
class Q_CORE_EXPORT QMetaCallEvent : public QAbstractMetaCallEvent
{
public:
- // blocking queued with semaphore - args always owned by caller
+ // blocking queued with latch - args always owned by caller
QMetaCallEvent(ushort method_offset, ushort method_relative,
QObjectPrivate::StaticMetaCallFunction callFunction,
const QObject *sender, int signalId,
- void **args, QSemaphore *semaphore);
+ void **args, QLatch *latch);
QMetaCallEvent(QtPrivate::QSlotObjectBase *slotObj,
const QObject *sender, int signalId,
- void **args, QSemaphore *semaphore);
+ void **args, QLatch *latch);
QMetaCallEvent(QtPrivate::SlotObjUniquePtr slotObj,
const QObject *sender, int signalId,
- void **args, QSemaphore *semaphore);
+ void **args, QLatch *latch);
// queued - args allocated by event, copied by caller
QMetaCallEvent(ushort method_offset, ushort method_relative,
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index ed17dddbcf5..4c9736dea6d 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -6,6 +6,7 @@
#include <qcoreapplication.h>
#include <qelapsedtimer.h>
+#include <private/qlatch_p.h>
#include <qloggingcategory.h>
#include <qmetaobject.h>
#include <qobject.h>
@@ -1530,8 +1531,8 @@ void QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg)
ObjectTreeNode result;
int usedLength;
QThread *objThread = nullptr;
- QSemaphore sem;
- bool semWait;
+ QLatch latch(1);
+ bool latchWait;
{
QDBusReadLocker locker(HandleObjectCallAction, this);
@@ -1569,16 +1570,16 @@ void QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg)
// synchronize with it
postEventToThread(HandleObjectCallPostEventAction, result.obj,
new QDBusActivateObjectEvent(QDBusConnection(this), this, result,
- usedLength, msg, &sem));
- semWait = true;
+ usedLength, msg, &latch));
+ latchWait = true;
} else {
// looped-back message, targeting current thread
- semWait = false;
+ latchWait = false;
}
} // release the lock
- if (semWait)
- SEM_ACQUIRE(HandleObjectCallSemaphoreAction, sem);
+ if (latchWait)
+ latch.wait();
else
activateObject(result, msg, usedLength);
}
diff --git a/src/dbus/qdbusintegrator_p.h b/src/dbus/qdbusintegrator_p.h
index 9c5fa1b061f..ac9adf02100 100644
--- a/src/dbus/qdbusintegrator_p.h
+++ b/src/dbus/qdbusintegrator_p.h
@@ -107,8 +107,8 @@ class QDBusActivateObjectEvent: public QAbstractMetaCallEvent
public:
QDBusActivateObjectEvent(const QDBusConnection &c, QObject *sender,
const QDBusConnectionPrivate::ObjectTreeNode &n,
- int p, const QDBusMessage &m, QSemaphore *s = nullptr)
- : QAbstractMetaCallEvent(sender, -1, s), connection(c), node(n),
+ int p, const QDBusMessage &m, QLatch *l = nullptr)
+ : QAbstractMetaCallEvent(sender, -1, l), connection(c), node(n),
pathStartPos(p), message(m), handled(false)
{ }
~QDBusActivateObjectEvent() override;
diff --git a/src/dbus/qdbusthreaddebug_p.h b/src/dbus/qdbusthreaddebug_p.h
index a1d3a420ec6..bcbd1efb494 100644
--- a/src/dbus/qdbusthreaddebug_p.h
+++ b/src/dbus/qdbusthreaddebug_p.h
@@ -129,25 +129,5 @@ struct QDBusWriteLocker: QDBusLockerBase
}
};
-#if QDBUS_THREAD_DEBUG
-# define SEM_ACQUIRE(action, sem) \
- do { \
- QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::BeforeAcquire, this); \
- sem.acquire(); \
- QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::AfterAcquire, this); \
- } while (false)
-
-# define SEM_RELEASE(action, sem) \
- do { \
- QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::BeforeRelease, that); \
- sem.release(); \
- QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::AfterRelease, that); \
- } while (false)
-
-#else
-# define SEM_ACQUIRE(action, sem) sem.acquire()
-# define SEM_RELEASE(action, sem) sem.release()
-#endif
-
#endif // QT_NO_DBUS
#endif
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 840bff26e53..1413e611270 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -38,7 +38,7 @@
#include <private/qfont_p.h>
#if QT_CONFIG(qtgui_threadpool)
-#include <qsemaphore.h>
+#include <private/qlatch_p.h>
#include <qthreadpool.h>
#include <private/qthreadpool_p.h>
#endif
@@ -5342,17 +5342,17 @@ void QImage::applyColorTransform(const QColorTransform &transform)
segments = std::min(segments, height());
QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool();
if (segments > 1 && threadPool && !threadPool->contains(QThread::currentThread())) {
- QSemaphore semaphore;
+ QLatch latch(segments);
int y = 0;
for (int i = 0; i < segments; ++i) {
int yn = (height() - y) / (segments - i);
threadPool->start([&, y, yn]() {
transformSegment(y, y + yn);
- semaphore.release(1);
+ latch.countDown();
});
y += yn;
}
- semaphore.acquire(segments);
+ latch.wait();
} else
#endif
transformSegment(0, height());
@@ -5832,17 +5832,17 @@ QImage QImage::colorTransformed(const QColorTransform &transform, QImage::Format
segments = std::min(segments, height());
QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool();
if (segments > 1 && threadPool && !threadPool->contains(QThread::currentThread())) {
- QSemaphore semaphore;
+ QLatch latch(segments);
int y = 0;
for (int i = 0; i < segments; ++i) {
int yn = (height() - y) / (segments - i);
threadPool->start([&, y, yn]() {
transformSegment(y, y + yn);
- semaphore.release(1);
+ latch.countDown();
});
y += yn;
}
- semaphore.acquire(segments);
+ latch.wait();
} else
#endif
transformSegment(0, height());
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index 43f3cca09e0..521d71796ea 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -14,7 +14,7 @@
#include <qendian.h>
#include <qrgbafloat.h>
#if QT_CONFIG(thread)
-#include <qsemaphore.h>
+#include <private/qlatch_p.h>
#include <qthreadpool.h>
#include <private/qthreadpool_p.h>
#endif
@@ -215,17 +215,17 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio
if (segments <= 1 || !threadPool || threadPool->contains(QThread::currentThread()))
return convertSegment(0, src->height);
- QSemaphore semaphore;
+ QLatch latch(segments);
int y = 0;
for (int i = 0; i < segments; ++i) {
int yn = (src->height - y) / (segments - i);
threadPool->start([&, y, yn]() {
convertSegment(y, y + yn);
- semaphore.release(1);
+ latch.countDown();
});
y += yn;
}
- semaphore.acquire(segments);
+ latch.wait();
#else
convertSegment(0, src->height);
#endif
@@ -270,17 +270,17 @@ void convert_generic_over_rgb64(QImageData *dest, const QImageData *src, Qt::Ima
if (segments <= 1 || !threadPool || threadPool->contains(QThread::currentThread()))
return convertSegment(0, src->height);
- QSemaphore semaphore;
+ QLatch latch(segments);
int y = 0;
for (int i = 0; i < segments; ++i) {
int yn = (src->height - y) / (segments - i);
threadPool->start([&, y, yn]() {
convertSegment(y, y + yn);
- semaphore.release(1);
+ latch.countDown();
});
y += yn;
}
- semaphore.acquire(segments);
+ latch.wait();
#else
convertSegment(0, src->height);
#endif
@@ -324,17 +324,17 @@ void convert_generic_over_rgba32f(QImageData *dest, const QImageData *src, Qt::I
if (segments <= 1 || !threadPool || threadPool->contains(QThread::currentThread()))
return convertSegment(0, src->height);
- QSemaphore semaphore;
+ QLatch latch(segments);
int y = 0;
for (int i = 0; i < segments; ++i) {
int yn = (src->height - y) / (segments - i);
threadPool->start([&, y, yn]() {
convertSegment(y, y + yn);
- semaphore.release(1);
+ latch.countDown();
});
y += yn;
}
- semaphore.acquire(segments);
+ latch.wait();
#else
convertSegment(0, src->height);
#endif
@@ -435,17 +435,17 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im
segments = std::min(segments, data->height);
QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool();
if (segments > 1 && threadPool && !threadPool->contains(QThread::currentThread())) {
- QSemaphore semaphore;
+ QLatch latch(segments);
int y = 0;
for (int i = 0; i < segments; ++i) {
int yn = (data->height - y) / (segments - i);
threadPool->start([&, y, yn]() {
convertSegment(y, y + yn);
- semaphore.release(1);
+ latch.countDown();
});
y += yn;
}
- semaphore.acquire(segments);
+ latch.wait();
if (data->bytes_per_line != params.bytesPerLine) {
// Compress segments to a continuous block
y = 0;
@@ -529,17 +529,17 @@ bool convert_generic_inplace_over_rgb64(QImageData *data, QImage::Format dst_for
segments = std::min(segments, data->height);
QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool();
if (segments > 1 && threadPool && !threadPool->contains(QThread::currentThread())) {
- QSemaphore semaphore;
+ QLatch latch(segments);
int y = 0;
for (int i = 0; i < segments; ++i) {
int yn = (data->height - y) / (segments - i);
threadPool->start([&, y, yn]() {
convertSegment(y, y + yn);
- semaphore.release(1);
+ latch.countDown();
});
y += yn;
}
- semaphore.acquire(segments);
+ latch.wait();
if (data->bytes_per_line != params.bytesPerLine) {
// Compress segments to a continuous block
y = 0;
@@ -624,17 +624,17 @@ bool convert_generic_inplace_over_rgba32f(QImageData *data, QImage::Format dst_f
segments = std::min(segments, data->height);
QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool();
if (segments > 1 && threadPool && !threadPool->contains(QThread::currentThread())) {
- QSemaphore semaphore;
+ QLatch latch(segments);
int y = 0;
for (int i = 0; i < segments; ++i) {
int yn = (data->height - y) / (segments - i);
threadPool->start([&, y, yn]() {
convertSegment(y, y + yn);
- semaphore.release(1);
+ latch.countDown();
});
y += yn;
}
- semaphore.acquire(segments);
+ latch.wait();
if (data->bytes_per_line != params.bytesPerLine) {
// Compress segments to a continuous block
y = 0;
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 8aefba86ee7..b109e9a5a20 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -28,7 +28,7 @@
#include <qmath.h>
#if QT_CONFIG(qtgui_threadpool)
-#include <qsemaphore.h>
+#include <private/qlatch_p.h>
#include <qthreadpool.h>
#include <private/qthreadpool_p.h>
#endif
@@ -3970,17 +3970,17 @@ static void spanfill_from_first(QRasterBuffer *rasterBuffer, QPixelLayout::BPP b
QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool(); \
if (segments > 1 && qPixelLayouts[data->rasterBuffer->format].bpp >= QPixelLayout::BPP8 \
&& threadPool && !threadPool->contains(QThread::currentThread())) { \
- QSemaphore semaphore; \
+ QLatch latch(segments); \
int c = 0; \
for (int i = 0; i < segments; ++i) { \
int cn = (count - c) / (segments - i); \
threadPool->start([&, c, cn]() { \
function(c, c + cn); \
- semaphore.release(1); \
+ latch.countDown(); \
}, 1); \
c += cn; \
} \
- semaphore.acquire(segments); \
+ latch.wait(); \
} else \
function(0, count)
#else
diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp
index 1bbfcf07a0a..15ef5f57dc7 100644
--- a/src/gui/painting/qimagescale.cpp
+++ b/src/gui/painting/qimagescale.cpp
@@ -11,7 +11,7 @@
#include "qrgbafloat.h"
#if QT_CONFIG(qtgui_threadpool)
-#include <qsemaphore.h>
+#include <private/qlatch_p.h>
#include <qthreadpool.h>
#include <private/qguiapplication_p.h>
#include <private/qthreadpool_p.h>
@@ -290,17 +290,17 @@ static inline void multithread_pixels_function(QImageScaleInfo *isi, int dh, con
segments = std::min(segments, dh);
QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool();
if (segments > 1 && threadPool && !threadPool->contains(QThread::currentThread())) {
- QSemaphore semaphore;
+ QLatch latch(segments);
int y = 0;
for (int i = 0; i < segments; ++i) {
int yn = (dh - y) / (segments - i);
threadPool->start([&, y, yn]() {
scaleSection(y, y + yn);
- semaphore.release(1);
+ latch.countDown();
});
y += yn;
}
- semaphore.acquire(segments);
+ latch.wait();
return;
}
#else
diff --git a/src/gui/painting/qimagescale_neon.cpp b/src/gui/painting/qimagescale_neon.cpp
index 1fc1070dc0d..81e04e8f082 100644
--- a/src/gui/painting/qimagescale_neon.cpp
+++ b/src/gui/painting/qimagescale_neon.cpp
@@ -7,7 +7,7 @@
#include <private/qsimd_p.h>
#if QT_CONFIG(qtgui_threadpool)
-#include <qsemaphore.h>
+#include <private/qlatch_p.h>
#include <qthreadpool.h>
#include <private/qguiapplication_p.h>
#include <private/qthreadpool_p.h>
@@ -27,17 +27,17 @@ static inline void multithread_pixels_function(QImageScaleInfo *isi, int dh, con
segments = std::min(segments, dh);
QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool();
if (segments > 1 && threadPool && !threadPool->contains(QThread::currentThread())) {
- QSemaphore semaphore;
+ QLatch semaphore(segments);
int y = 0;
for (int i = 0; i < segments; ++i) {
int yn = (dh - y) / (segments - i);
threadPool->start([&, y, yn]() {
scaleSection(y, y + yn);
- semaphore.release(1);
+ semaphore.countDown();
});
y += yn;
}
- semaphore.acquire(segments);
+ semaphore.wait();
return;
}
#endif
diff --git a/src/gui/painting/qimagescale_sse4.cpp b/src/gui/painting/qimagescale_sse4.cpp
index 5d4c3a4e7c2..740f1570345 100644
--- a/src/gui/painting/qimagescale_sse4.cpp
+++ b/src/gui/painting/qimagescale_sse4.cpp
@@ -7,7 +7,7 @@
#include <private/qsimd_p.h>
#if QT_CONFIG(qtgui_threadpool)
-#include <qsemaphore.h>
+#include <private/qlatch_p.h>
#include <qthreadpool.h>
#include <private/qguiapplication_p.h>
#include <private/qthreadpool_p.h>
@@ -27,17 +27,17 @@ static inline void multithread_pixels_function(QImageScaleInfo *isi, int dh, con
segments = std::min(segments, dh);
QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool();
if (segments > 1 && threadPool && !threadPool->contains(QThread::currentThread())) {
- QSemaphore semaphore;
+ QLatch latch(segments);
int y = 0;
for (int i = 0; i < segments; ++i) {
int yn = (dh - y) / (segments - i);
threadPool->start([&, y, yn]() {
scaleSection(y, y + yn);
- semaphore.release(1);
+ latch.countDown();
});
y += yn;
}
- semaphore.acquire(segments);
+ latch.wait();
return;
}
#endif
diff --git a/src/network/kernel/qnetworkproxy_libproxy.cpp b/src/network/kernel/qnetworkproxy_libproxy.cpp
index da1e8fdbd4a..b17d46ea96a 100644
--- a/src/network/kernel/qnetworkproxy_libproxy.cpp
+++ b/src/network/kernel/qnetworkproxy_libproxy.cpp
@@ -10,6 +10,7 @@
#include <QtCore/QMutex>
#include <QtCore/QSemaphore>
#include <QtCore/QUrl>
+#include <QtCore/private/qlatch_p.h>
#include <QtCore/private/qeventdispatcher_unix_p.h>
#include <QtCore/private/qthread_p.h>
#include <QtCore/qapplicationstatic.h>
@@ -61,7 +62,7 @@ private:
// we leave the conversion to/from QUrl to the calling thread
const char *url;
char **proxies;
- QSemaphore replyReady;
+ QLatch replyReady{1};
};
void run() override;
@@ -119,7 +120,7 @@ QList<QUrl> QLibProxyWrapper::getProxies(const QUrl &url)
requestReady.release();
// wait for the reply
- data.replyReady.acquire();
+ data.replyReady.wait();
} else {
// non-threaded mode
data.proxies = px_proxy_factory_get_proxies(factory, data.url);
@@ -147,7 +148,7 @@ void QLibProxyWrapper::run()
if (isInterruptionRequested())
break;
request->proxies = px_proxy_factory_get_proxies(factory, request->url);
- request->replyReady.release();
+ request->replyReady.countDown();
}
px_proxy_factory_free(factory);
diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp
index 851fef2e05a..a293023f2c6 100644
--- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp
+++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp
@@ -10,7 +10,7 @@
#endif
#include <QScopeGuard>
#include <QVersionNumber>
-#include <QSemaphore>
+#include <private/qlatch_p.h>
#include <qcoreapplication.h>
#include <qfileinfo.h>
@@ -1926,13 +1926,13 @@ void tst_QUdpSocket::readyReadConnectionThrottling()
QUdpSocket receiver;
QVERIFY(receiver.bind(QHostAddress(QHostAddress::LocalHost), 0));
- QSemaphore semaphore;
+ QLatch latch(1);
// Repro-ing deterministically eludes me, so we are bruteforcing it:
// The thread acts as a remote sender, flooding the receiver with datagrams,
// and at some point the receiver would get into the broken state mentioned
// earlier.
- std::unique_ptr<QThread> thread(QThread::create([&semaphore, port = receiver.localPort()]() {
+ std::unique_ptr<QThread> thread(QThread::create([&latch, port = receiver.localPort()]() {
QUdpSocket sender;
sender.connectToHost(QHostAddress(QHostAddress::LocalHost), port);
QCOMPARE(sender.state(), QUdpSocket::ConnectedState);
@@ -1940,7 +1940,7 @@ void tst_QUdpSocket::readyReadConnectionThrottling()
constexpr qsizetype PayloadSize = 242;
const QByteArray payload(PayloadSize, 'a');
- semaphore.acquire(); // Wait for main thread to be ready
+ latch.wait(); // Wait for main thread to be ready
while (true) {
// We send 100 datagrams at a time, then sleep.
// This is mostly to let the main thread catch up between bursts so
@@ -1975,7 +1975,7 @@ void tst_QUdpSocket::readyReadConnectionThrottling()
},
Qt::QueuedConnection);
- semaphore.release();
+ latch.countDown();
constexpr qsizetype MaxCount = 500;
QVERIFY2(QTest::qWaitFor([&] { return count >= MaxCount; }, 10s),
QByteArray::number(count).constData());