Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qeventdispatcher_cf_p.h
Go to the documentation of this file.
1// Copyright (c) 2007-2008, Apple, Inc.
2// SPDX-License-Identifier: BSD-3-Clause
3// Qt-Security score:significant reason:default
4
5#ifndef QEVENTDISPATCHER_CF_P_H
6#define QEVENTDISPATCHER_CF_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtCore/qabstracteventdispatcher.h>
20#include <QtCore/private/qtimerinfo_unix_p.h>
21#include <QtCore/private/qcfsocketnotifier_p.h>
22#include <QtCore/private/qcore_mac_p.h>
23#include <QtCore/qloggingcategory.h>
24
25#include <CoreFoundation/CoreFoundation.h>
26
27Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(RunLoopModeTracker));
28
29QT_BEGIN_NAMESPACE
30
31namespace QtPrivate {
34}
35
36class QEventDispatcherCoreFoundation;
37
38template <class T = QEventDispatcherCoreFoundation>
40{
41public:
42 typedef bool (T::*CallbackFunction)();
43
44 enum { kHighestPriority = 0 } RunLoopSourcePriority;
45
46 RunLoopSource(T *delegate, CallbackFunction callback)
47 : m_delegate(delegate), m_callback(callback)
48 {
49 CFRunLoopSourceContext context = {};
50 context.info = this;
51 context.perform = RunLoopSource::process;
52
53 m_source = CFRunLoopSourceCreate(kCFAllocatorDefault, kHighestPriority, &context);
54 Q_ASSERT(m_source);
55 }
56
58 {
59 CFRunLoopSourceInvalidate(m_source);
60 CFRelease(m_source);
61 }
62
63 void addToMode(CFStringRef mode, CFRunLoopRef runLoop = 0)
64 {
65 if (!runLoop)
66 runLoop = CFRunLoopGetCurrent();
67
68 CFRunLoopAddSource(runLoop, m_source, mode);
69 }
70
71 void signal() { CFRunLoopSourceSignal(m_source); }
72
73private:
74 static void process(void *info)
75 {
76 RunLoopSource *self = static_cast<RunLoopSource *>(info);
77 ((self->m_delegate)->*(self->m_callback))();
78 }
79
80 T *m_delegate;
81 CallbackFunction m_callback;
82 CFRunLoopSourceRef m_source;
83};
84
85template <class T = QEventDispatcherCoreFoundation>
87{
88public:
89 typedef void (T::*CallbackFunction) (CFRunLoopActivity activity);
90
91 RunLoopObserver(T *delegate, CallbackFunction callback, CFOptionFlags activities)
92 : m_delegate(delegate), m_callback(callback)
93 {
94 CFRunLoopObserverContext context = {};
95 context.info = this;
96
97 m_observer = CFRunLoopObserverCreate(kCFAllocatorDefault, activities, true, 0, process, &context);
98 Q_ASSERT(m_observer);
99 }
100
102 {
103 CFRunLoopObserverInvalidate(m_observer);
104 CFRelease(m_observer);
105 }
106
107 void addToMode(CFStringRef mode, CFRunLoopRef runLoop = 0)
108 {
109 if (!runLoop)
110 runLoop = CFRunLoopGetCurrent();
111
112 if (!CFRunLoopContainsObserver(runLoop, m_observer, mode))
113 CFRunLoopAddObserver(runLoop, m_observer, mode);
114 }
115
116 void removeFromMode(CFStringRef mode, CFRunLoopRef runLoop = 0)
117 {
118 if (!runLoop)
119 runLoop = CFRunLoopGetCurrent();
120
121 if (CFRunLoopContainsObserver(runLoop, m_observer, mode))
122 CFRunLoopRemoveObserver(runLoop, m_observer, mode);
123 }
124
125private:
126 static void process(CFRunLoopObserverRef, CFRunLoopActivity activity, void *info)
127 {
128 RunLoopObserver *self = static_cast<RunLoopObserver *>(info);
129 ((self->m_delegate)->*(self->m_callback))(activity);
130 }
131
132 T *m_delegate;
133 CallbackFunction m_callback;
134 CFRunLoopObserverRef m_observer;
135};
136
137class Q_CORE_EXPORT QEventDispatcherCoreFoundation : public QAbstractEventDispatcherV2
138{
139 Q_OBJECT
140
141public:
142 explicit QEventDispatcherCoreFoundation(QObject *parent = nullptr);
143 void startingUp() override;
144 ~QEventDispatcherCoreFoundation();
145
146 bool processEvents(QEventLoop::ProcessEventsFlags flags) override;
147
148 void registerSocketNotifier(QSocketNotifier *notifier) override;
149 void unregisterSocketNotifier(QSocketNotifier *notifier) override;
150
151 void registerTimer(Qt::TimerId timerId, Duration interval, Qt::TimerType timerType,
152 QObject *object) override final;
153 bool unregisterTimer(Qt::TimerId timerId) override final;
154 bool unregisterTimers(QObject *object) override final;
155 QList<TimerInfoV2> timersForObject(QObject *object) const override final;
156 Duration remainingTime(Qt::TimerId timerId) const override final;
157
158 void wakeUp() override;
159 void interrupt() override;
160
161protected:
162 QEventLoop *currentEventLoop() const;
163
164 virtual bool processPostedEvents();
165
166 struct ProcessEventsState
167 {
168 ProcessEventsState(QEventLoop::ProcessEventsFlags f)
169 : flags(f.toInt()), wasInterrupted(false)
170 , processedPostedEvents(false), processedTimers(false)
171 , deferredWakeUp(false), deferredUpdateTimers(false) {}
172
173 ProcessEventsState(const ProcessEventsState &other)
174 : flags(other.flags.loadAcquire())
175 , wasInterrupted(other.wasInterrupted.loadAcquire())
176 , processedPostedEvents(other.processedPostedEvents.loadAcquire())
177 , processedTimers(other.processedTimers.loadAcquire())
178 , deferredWakeUp(other.deferredWakeUp.loadAcquire())
179 , deferredUpdateTimers(other.deferredUpdateTimers) {}
180
181 ProcessEventsState &operator=(const ProcessEventsState &other)
182 {
183 flags.storeRelease(other.flags.loadAcquire());
184 wasInterrupted.storeRelease(other.wasInterrupted.loadAcquire());
185 processedPostedEvents.storeRelease(other.processedPostedEvents.loadAcquire());
186 processedTimers.storeRelease(other.processedTimers.loadAcquire());
187 deferredWakeUp.storeRelease(other.deferredWakeUp.loadAcquire());
188 deferredUpdateTimers = other.deferredUpdateTimers;
189 return *this;
190 }
191
192 QAtomicInt flags;
193 QAtomicInteger<char> wasInterrupted;
194 QAtomicInteger<char> processedPostedEvents;
195 QAtomicInteger<char> processedTimers;
196 QAtomicInteger<char> deferredWakeUp;
197 bool deferredUpdateTimers;
198 };
199
200 ProcessEventsState m_processEvents;
201
202private:
203 RunLoopSource<> m_postedEventsRunLoopSource;
204 RunLoopObserver<> m_runLoopActivityObserver;
205
206 QT_MANGLE_NAMESPACE(RunLoopModeTracker) *m_runLoopModeTracker;
207
208 QTimerInfoList m_timerInfoList;
209 CFRunLoopTimerRef m_runLoopTimer;
210 CFRunLoopTimerRef m_blockedRunLoopTimer;
211 QCFType<CFRunLoopRef> m_runLoop;
212 bool m_overdueTimerScheduled;
213
214 QCFSocketNotifier m_cfSocketNotifier;
215
216 void processTimers(CFRunLoopTimerRef);
217
218 void handleRunLoopActivity(CFRunLoopActivity activity);
219
220 void updateTimers();
221 void invalidateTimer();
222};
223
224QT_END_NAMESPACE
225
226#endif // QEVENTDISPATCHER_CF_P_H
void(T::* CallbackFunction)(CFRunLoopActivity activity)
void addToMode(CFStringRef mode, CFRunLoopRef runLoop=0)
RunLoopObserver(T *delegate, CallbackFunction callback, CFOptionFlags activities)
void removeFromMode(CFStringRef mode, CFRunLoopRef runLoop=0)
void addToMode(CFStringRef mode, CFRunLoopRef runLoop=0)
RunLoopSource(T *delegate, CallbackFunction callback)
bool(T::* CallbackFunction)()
Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher")
QDebug operator<<(QDebug debug, QDir::Filters filters)
Definition qdir.cpp:2582
#define Q_ENUM_PRINTER(enumName)
#define Q_MIRROR_ENUM(name)
static const CFTimeInterval kCFTimeIntervalMinimum
static const CFTimeInterval kCFTimeIntervalDistantFuture
Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(RunLoopModeTracker))
QT_BEGIN_NAMESPACE Q_STATIC_LOGGING_CATEGORY(lcSynthesizedIterableAccess, "qt.iterable.synthesized", QtWarningMsg)