1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2016 Intel Corporation.
3// Copyright (C) 2012 Olivier Goffart <ogoffart@woboq.com>
4// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
5
6#ifndef QMUTEX_P_H
7#define QMUTEX_P_H
8
9//
10// W A R N I N G
11// -------------
12//
13// This file is not part of the Qt API. It exists for the convenience of
14// qmutex.cpp and qmutex_unix.cpp. This header file may change from version to
15// version without notice, or even be removed.
16//
17// We mean it.
18//
19
20#include <QtCore/private/qglobal_p.h>
21#include <QtCore/qnamespace.h>
22#include <QtCore/qmutex.h>
23#include <QtCore/qatomic.h>
24#include <QtCore/qdeadlinetimer.h>
25
26#include "qplatformdefs.h" // _POSIX_VERSION
27
28#if defined(Q_OS_DARWIN)
29# include <mach/semaphore.h>
30#elif defined(Q_OS_UNIX)
31# include <semaphore.h>
32#endif
33
34struct timespec;
35
36QT_BEGIN_NAMESPACE
37
38// We manipulate the pointer to this class in inline, atomic code,
39// so syncqt mustn't mark them as private, so ELFVERSION:ignore-next
40class QMutexPrivate
41{
42public:
43 ~QMutexPrivate();
44 QMutexPrivate();
45
46 bool wait(QDeadlineTimer timeout = QDeadlineTimer::Forever);
47 void wakeUp() noexcept;
48
49 // Control the lifetime of the privates
50 QAtomicInt refCount;
51 int id;
52
53 bool ref()
54 {
55 Q_ASSERT(refCount.loadRelaxed() >= 0);
56 int c;
57 do {
58 c = refCount.loadRelaxed();
59 if (c == 0)
60 return false;
61 } while (!refCount.testAndSetRelaxed(expectedValue: c, newValue: c + 1));
62 Q_ASSERT(refCount.loadRelaxed() >= 0);
63 return true;
64 }
65 void deref()
66 {
67 Q_ASSERT(refCount.loadRelaxed() >= 0);
68 if (!refCount.deref())
69 release();
70 Q_ASSERT(refCount.loadRelaxed() >= 0);
71 }
72 void release();
73 static QMutexPrivate *allocate();
74
75 QAtomicInt waiters; // Number of threads waiting on this mutex. (may be offset by -BigNumber)
76 QAtomicInt possiblyUnlocked; /* Boolean indicating that a timed wait timed out.
77 When it is true, a reference is held.
78 It is there to avoid a race that happens if unlock happens right
79 when the mutex is unlocked.
80 */
81 enum { BigNumber = 0x100000 }; //Must be bigger than the possible number of waiters (number of threads)
82 void derefWaiters(int value) noexcept;
83
84 //platform specific stuff
85#if defined(Q_OS_DARWIN)
86 semaphore_t mach_semaphore;
87#elif defined(Q_OS_UNIX)
88 sem_t semaphore;
89#endif
90};
91
92QT_END_NAMESPACE
93
94#endif // QMUTEX_P_H
95

source code of qtbase/src/corelib/thread/qmutex_p.h