File indexing completed on 2026-01-06 10:21:32
0001
0002
0003
0004
0005 #ifndef QSEMAPHORE_H
0006 #define QSEMAPHORE_H
0007
0008 #include <QtCore/qglobal.h>
0009 #include <QtCore/qdeadlinetimer.h>
0010
0011 #include <chrono>
0012
0013 QT_BEGIN_NAMESPACE
0014
0015 class QSemaphorePrivate;
0016 class Q_CORE_EXPORT QSemaphore
0017 {
0018 public:
0019 explicit QSemaphore(int n = 0);
0020 ~QSemaphore();
0021
0022 void acquire(int n = 1);
0023 bool tryAcquire(int n = 1);
0024 QT_CORE_INLINE_SINCE(6, 6)
0025 bool tryAcquire(int n, int timeout);
0026 bool tryAcquire(int n, QDeadlineTimer timeout);
0027 #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
0028 template <typename Rep, typename Period>
0029 bool tryAcquire(int n, std::chrono::duration<Rep, Period> timeout)
0030 { return tryAcquire(n, QDeadlineTimer(timeout)); }
0031 #endif
0032
0033 void release(int n = 1);
0034
0035 int available() const;
0036
0037
0038 bool try_acquire() noexcept { return tryAcquire(); }
0039 template <typename Rep, typename Period>
0040 bool try_acquire_for(const std::chrono::duration<Rep, Period> &timeout)
0041 { return tryAcquire(1, timeout); }
0042 template <typename Clock, typename Duration>
0043 bool try_acquire_until(const std::chrono::time_point<Clock, Duration> &tp)
0044 {
0045 return try_acquire_for(tp - Clock::now());
0046 }
0047 private:
0048 Q_DISABLE_COPY(QSemaphore)
0049
0050 union {
0051 QSemaphorePrivate *d;
0052 QBasicAtomicInteger<quintptr> u;
0053 QBasicAtomicInteger<quint32> u32[2];
0054 QBasicAtomicInteger<quint64> u64;
0055 };
0056 };
0057
0058 #if QT_CORE_INLINE_IMPL_SINCE(6, 6)
0059 bool QSemaphore::tryAcquire(int n, int timeout)
0060 {
0061 return tryAcquire(n, QDeadlineTimer(timeout));
0062 }
0063 #endif
0064
0065 class QSemaphoreReleaser
0066 {
0067 public:
0068 Q_NODISCARD_CTOR
0069 QSemaphoreReleaser() = default;
0070 Q_NODISCARD_CTOR
0071 explicit QSemaphoreReleaser(QSemaphore &sem, int n = 1) noexcept
0072 : m_sem(&sem), m_n(n) {}
0073 Q_NODISCARD_CTOR
0074 explicit QSemaphoreReleaser(QSemaphore *sem, int n = 1) noexcept
0075 : m_sem(sem), m_n(n) {}
0076 Q_NODISCARD_CTOR
0077 QSemaphoreReleaser(QSemaphoreReleaser &&other) noexcept
0078 : m_sem(other.cancel()), m_n(other.m_n) {}
0079 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QSemaphoreReleaser)
0080
0081 ~QSemaphoreReleaser()
0082 {
0083 if (m_sem)
0084 m_sem->release(m_n);
0085 }
0086
0087 void swap(QSemaphoreReleaser &other) noexcept
0088 {
0089 qt_ptr_swap(m_sem, other.m_sem);
0090 std::swap(m_n, other.m_n);
0091 }
0092
0093 QSemaphore *semaphore() const noexcept
0094 { return m_sem; }
0095
0096 QSemaphore *cancel() noexcept
0097 {
0098 return std::exchange(m_sem, nullptr);
0099 }
0100
0101 private:
0102 QSemaphore *m_sem = nullptr;
0103 int m_n = 0;
0104 };
0105
0106 QT_END_NAMESPACE
0107
0108 #endif