summaryrefslogtreecommitdiffstats
path: root/src/platformsupport
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@digia.com>2013-06-17 12:57:48 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-08-23 11:28:48 +0200
commitc0e5f31ad8621127af17ae8cc1660a249391d1eb (patch)
tree4e71dcaf99a376174feaa6a4f0f2bea5b5d5c327 /src/platformsupport
parent29c1567ee4724b02995060035df8d93f7d6d9c37 (diff)
iOS: Wrap CFRunLoopSource in C++ class for easier code legibility
Change-Id: If34953b171676f0246c2fb5e60c59f59350863ec Reviewed-by: Ian Dean <ian@mediator-software.com> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@digia.com>
Diffstat (limited to 'src/platformsupport')
-rw-r--r--src/platformsupport/eventdispatchers/qeventdispatcher_cf.mm81
-rw-r--r--src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h56
2 files changed, 77 insertions, 60 deletions
diff --git a/src/platformsupport/eventdispatchers/qeventdispatcher_cf.mm b/src/platformsupport/eventdispatchers/qeventdispatcher_cf.mm
index 55d40937b7..d270dbcfcb 100644
--- a/src/platformsupport/eventdispatchers/qeventdispatcher_cf.mm
+++ b/src/platformsupport/eventdispatchers/qeventdispatcher_cf.mm
@@ -50,17 +50,6 @@
QT_BEGIN_NAMESPACE
QT_USE_NAMESPACE
-static Boolean runLoopSourceEqualCallback(const void *info1, const void *info2)
-{
- return info1 == info2;
-}
-
-void QEventDispatcherCoreFoundation::postedEventsRunLoopCallback(void *info)
-{
- QEventDispatcherCoreFoundation *self = static_cast<QEventDispatcherCoreFoundation *>(info);
- self->processPostedEvents();
-}
-
void QEventDispatcherCoreFoundation::nonBlockingTimerRunLoopCallback(CFRunLoopTimerRef, void *info)
{
// The (one and only) CFRunLoopTimer has fired, which means that at least
@@ -69,19 +58,8 @@ void QEventDispatcherCoreFoundation::nonBlockingTimerRunLoopCallback(CFRunLoopTi
// timers will stop working. The work-around is to forward the callback to a
// dedicated CFRunLoopSource that can recurse:
QEventDispatcherCoreFoundation *self = static_cast<QEventDispatcherCoreFoundation *>(info);
- CFRunLoopSourceSignal(self->m_blockingTimerRunLoopSource);
-}
-
-void QEventDispatcherCoreFoundation::blockingTimerRunLoopCallback(void *info)
-{
- // TODO:
- // We also need to block this new timer source
- // along with the posted event source when calling processEvents()
- // "manually" to prevent livelock deep in CFRunLoop.
-
- QEventDispatcherCoreFoundation *self = static_cast<QEventDispatcherCoreFoundation *>(info);
- self->m_timerInfoList.activateTimers();
- self->maybeStartCFRunLoopTimer();
+ self->m_blockingTimerRunLoopSource.signal();
+ // FIXME: And not wake up main run loop?
}
void QEventDispatcherCoreFoundation::maybeStartCFRunLoopTimer()
@@ -147,54 +125,45 @@ void QEventDispatcherCoreFoundation::maybeStopCFRunLoopTimer()
m_runLoopTimerRef = 0;
}
-void QEventDispatcherCoreFoundation::processPostedEvents()
-{
- QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::AllEvents);
-}
-
QEventDispatcherCoreFoundation::QEventDispatcherCoreFoundation(QObject *parent)
: QAbstractEventDispatcher(parent)
, m_interrupted(false)
+ , m_postedEventsRunLoopSource(this, &QEventDispatcherCoreFoundation::processPostedEvents)
+ , m_blockingTimerRunLoopSource(this, &QEventDispatcherCoreFoundation::processTimers)
, m_runLoopTimerRef(0)
{
m_cfSocketNotifier.setHostEventDispatcher(this);
- CFRunLoopRef mainRunLoop = CFRunLoopGetMain();
- CFRunLoopSourceContext context;
- bzero(&context, sizeof(CFRunLoopSourceContext));
- context.equal = runLoopSourceEqualCallback;
- context.info = this;
-
- // source used to handle timers:
- context.perform = QEventDispatcherCoreFoundation::blockingTimerRunLoopCallback;
- m_blockingTimerRunLoopSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
- Q_ASSERT(m_blockingTimerRunLoopSource);
- CFRunLoopAddSource(mainRunLoop, m_blockingTimerRunLoopSource, kCFRunLoopCommonModes);
- CFRunLoopAddSource(mainRunLoop, m_blockingTimerRunLoopSource, (CFStringRef) UITrackingRunLoopMode);
-
- // source used to handle posted events:
- context.perform = QEventDispatcherCoreFoundation::postedEventsRunLoopCallback;
- m_postedEventsRunLoopSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
- Q_ASSERT(m_postedEventsRunLoopSource);
- CFRunLoopAddSource(mainRunLoop, m_postedEventsRunLoopSource, kCFRunLoopCommonModes);
+ m_postedEventsRunLoopSource.addToMode(kCFRunLoopCommonModes);
+
+ m_blockingTimerRunLoopSource.addToMode(kCFRunLoopCommonModes);
+ m_blockingTimerRunLoopSource.addToMode(CFStringRef(UITrackingRunLoopMode));
}
QEventDispatcherCoreFoundation::~QEventDispatcherCoreFoundation()
{
- CFRunLoopRef mainRunLoop = CFRunLoopGetMain();
- CFRunLoopRemoveSource(mainRunLoop, m_postedEventsRunLoopSource, kCFRunLoopCommonModes);
- CFRelease(m_postedEventsRunLoopSource);
-
qDeleteAll(m_timerInfoList);
maybeStopCFRunLoopTimer();
- CFRunLoopRemoveSource(mainRunLoop, m_blockingTimerRunLoopSource, kCFRunLoopCommonModes);
- CFRunLoopRemoveSource(mainRunLoop, m_blockingTimerRunLoopSource, (CFStringRef) UITrackingRunLoopMode);
- CFRelease(m_blockingTimerRunLoopSource);
-
m_cfSocketNotifier.removeSocketNotifiers();
}
+void QEventDispatcherCoreFoundation::processPostedEvents()
+{
+ QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::AllEvents);
+}
+
+void QEventDispatcherCoreFoundation::processTimers()
+{
+ // TODO:
+ // We also need to block this new timer source
+ // along with the posted event source when calling processEvents()
+ // "manually" to prevent livelock deep in CFRunLoop.
+
+ m_timerInfoList.activateTimers();
+ maybeStartCFRunLoopTimer();
+}
+
bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlags flags)
{
m_interrupted = false;
@@ -336,7 +305,7 @@ int QEventDispatcherCoreFoundation::remainingTime(int timerId)
void QEventDispatcherCoreFoundation::wakeUp()
{
- CFRunLoopSourceSignal(m_postedEventsRunLoopSource);
+ m_postedEventsRunLoopSource.signal();
CFRunLoopWakeUp(CFRunLoopGetMain());
}
diff --git a/src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h b/src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h
index 6e5ce658a8..e12098d814 100644
--- a/src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h
+++ b/src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h
@@ -83,6 +83,55 @@
QT_BEGIN_NAMESPACE
+class QEventDispatcherCoreFoundation;
+
+template <class T = QEventDispatcherCoreFoundation>
+class RunLoopSource
+{
+public:
+ typedef void (T::*CallbackFunction) ();
+
+ enum { kHighestPriority = 0 } RunLoopSourcePriority;
+
+ RunLoopSource(T *delegate, CallbackFunction callback)
+ : m_delegate(delegate), m_callback(callback)
+ {
+ CFRunLoopSourceContext context = {};
+ context.info = this;
+ context.perform = RunLoopSource::process;
+
+ m_source = CFRunLoopSourceCreate(kCFAllocatorDefault, kHighestPriority, &context);
+ Q_ASSERT(m_source);
+ }
+
+ ~RunLoopSource()
+ {
+ CFRunLoopSourceInvalidate(m_source);
+ CFRelease(m_source);
+ }
+
+ void addToMode(CFStringRef mode, CFRunLoopRef runLoop = 0)
+ {
+ if (!runLoop)
+ runLoop = CFRunLoopGetCurrent();
+
+ CFRunLoopAddSource(runLoop, m_source, mode);
+ }
+
+ void signal() { CFRunLoopSourceSignal(m_source); }
+
+private:
+ static void process(void *info)
+ {
+ RunLoopSource *self = static_cast<RunLoopSource *>(info);
+ ((self->m_delegate)->*(self->m_callback))();
+ }
+
+ T *m_delegate;
+ CallbackFunction m_callback;
+ CFRunLoopSourceRef m_source;
+};
+
class QEventDispatcherCoreFoundation : public QAbstractEventDispatcher
{
Q_OBJECT
@@ -111,8 +160,8 @@ public:
private:
bool m_interrupted;
- CFRunLoopSourceRef m_postedEventsRunLoopSource;
- CFRunLoopSourceRef m_blockingTimerRunLoopSource;
+ RunLoopSource<> m_postedEventsRunLoopSource;
+ RunLoopSource<> m_blockingTimerRunLoopSource;
QTimerInfoList m_timerInfoList;
CFRunLoopTimerRef m_runLoopTimerRef;
@@ -120,12 +169,11 @@ private:
QCFSocketNotifier m_cfSocketNotifier;
void processPostedEvents();
+ void processTimers();
void maybeStartCFRunLoopTimer();
void maybeStopCFRunLoopTimer();
- static void postedEventsRunLoopCallback(void *info);
static void nonBlockingTimerRunLoopCallback(CFRunLoopTimerRef, void *info);
- static void blockingTimerRunLoopCallback(void *info);
};
QT_END_NAMESPACE