Modernize logging in CoreFoundation and iOS event dispatchers
Instead of manually handling logging enablement, we use Qt's categorized logging system. Change-Id: I8d942601f76876030084c9fb130b7215ff6cc404 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>bb10
parent
b1fe198d87
commit
f4765ff5f6
|
|
@ -112,14 +112,15 @@ static CFStringRef runLoopMode(NSDictionary *dictionary)
|
|||
if (CFStringRef mode = runLoopMode(notification.userInfo))
|
||||
m_runLoopModes.push(mode);
|
||||
else
|
||||
qWarning("Encountered run loop push notification without run loop mode!");
|
||||
qCWarning(lcEventDispatcher) << "Encountered run loop push notification without run loop mode!";
|
||||
|
||||
} else if (CFStringHasSuffix((CFStringRef)notification.name, CFSTR("RunLoopModePopNotification"))) {
|
||||
CFStringRef mode = runLoopMode(notification.userInfo);
|
||||
if (CFStringCompare(mode, [self currentMode], 0) == kCFCompareEqualTo)
|
||||
m_runLoopModes.pop();
|
||||
else
|
||||
qWarning("Tried to pop run loop mode '%s' that was never pushed!", qPrintable(QString::fromCFString(mode)));
|
||||
qCWarning(lcEventDispatcher) << "Tried to pop run loop mode"
|
||||
<< qPrintable(QString::fromCFString(mode)) << "that was never pushed!";
|
||||
|
||||
Q_ASSERT(m_runLoopModes.size() >= 1);
|
||||
}
|
||||
|
|
@ -134,6 +135,9 @@ static CFStringRef runLoopMode(NSDictionary *dictionary)
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher");
|
||||
Q_LOGGING_CATEGORY(lcEventDispatcherTimers, "qt.eventdispatcher.timers");
|
||||
|
||||
class RunLoopDebugger : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
@ -177,10 +181,6 @@ QDebug operator<<(QDebug s, timespec tv)
|
|||
return s;
|
||||
}
|
||||
|
||||
#if DEBUG_EVENT_DISPATCHER
|
||||
uint g_eventDispatcherIndentationLevel = 0;
|
||||
#endif
|
||||
|
||||
static const CFTimeInterval kCFTimeIntervalMinimum = 0;
|
||||
static const CFTimeInterval kCFTimeIntervalDistantFuture = std::numeric_limits<CFTimeInterval>::max();
|
||||
|
||||
|
|
@ -190,13 +190,7 @@ QEventDispatcherCoreFoundation::QEventDispatcherCoreFoundation(QObject *parent)
|
|||
: QAbstractEventDispatcher(parent)
|
||||
, m_processEvents(QEventLoop::EventLoopExec)
|
||||
, m_postedEventsRunLoopSource(this, &QEventDispatcherCoreFoundation::processPostedEvents)
|
||||
, m_runLoopActivityObserver(this, &QEventDispatcherCoreFoundation::handleRunLoopActivity,
|
||||
#if DEBUG_EVENT_DISPATCHER
|
||||
kCFRunLoopAllActivities
|
||||
#else
|
||||
kCFRunLoopBeforeWaiting | kCFRunLoopAfterWaiting
|
||||
#endif
|
||||
)
|
||||
, m_runLoopActivityObserver(this, &QEventDispatcherCoreFoundation::handleRunLoopActivity, kCFRunLoopAllActivities)
|
||||
, m_runLoopModeTracker([[RunLoopModeTracker alloc] init])
|
||||
, m_runLoopTimer(0)
|
||||
, m_blockedRunLoopTimer(0)
|
||||
|
|
@ -247,14 +241,14 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag
|
|||
bool eventsProcessed = false;
|
||||
|
||||
if (flags & (QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers))
|
||||
qWarning() << "processEvents() flags" << flags << "not supported on iOS";
|
||||
qCWarning(lcEventDispatcher) << "processEvents() flags" << flags << "not supported on iOS";
|
||||
|
||||
qEventDispatcherDebug() << "Entering with " << flags; qIndent();
|
||||
qCDebug(lcEventDispatcher) << "Processing events with flags" << flags;
|
||||
|
||||
if (m_blockedRunLoopTimer) {
|
||||
Q_ASSERT(m_blockedRunLoopTimer == m_runLoopTimer);
|
||||
|
||||
qEventDispatcherDebug() << "Recursing from blocked timer " << m_blockedRunLoopTimer;
|
||||
qCDebug(lcEventDispatcher) << "Recursing from blocked timer" << m_blockedRunLoopTimer;
|
||||
m_runLoopTimer = 0; // Unset current timer to force creation of new timer
|
||||
updateTimers();
|
||||
}
|
||||
|
|
@ -266,7 +260,7 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag
|
|||
m_postedEventsRunLoopSource.signal();
|
||||
m_processEvents.deferredWakeUp = false;
|
||||
|
||||
qEventDispatcherDebug() << "Processed deferred wake-up";
|
||||
qCDebug(lcEventDispatcher) << "Processed deferred wake-up";
|
||||
}
|
||||
|
||||
// The documentation states that this signal is emitted after the event
|
||||
|
|
@ -287,12 +281,12 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag
|
|||
CFTimeInterval duration = (m_processEvents.flags & QEventLoop::WaitForMoreEvents) ?
|
||||
kCFTimeIntervalDistantFuture : kCFTimeIntervalMinimum;
|
||||
|
||||
qEventDispatcherDebug() << "Calling CFRunLoopRunInMode = " << qPrintable(QString::fromCFString(mode))
|
||||
<< " for " << duration << " ms, processing single source = " << returnAfterSingleSourceHandled; qIndent();
|
||||
qCDebug(lcEventDispatcher) << "Calling CFRunLoopRunInMode =" << qPrintable(QString::fromCFString(mode))
|
||||
<< "for" << duration << "ms, processing single source =" << returnAfterSingleSourceHandled;
|
||||
|
||||
SInt32 result = CFRunLoopRunInMode(mode, duration, returnAfterSingleSourceHandled);
|
||||
|
||||
qUnIndent(); qEventDispatcherDebug() << "result = " << qPrintableResult(result);
|
||||
qCDebug(lcEventDispatcher) << "result =" << qPrintableResult(result);
|
||||
|
||||
eventsProcessed |= (result == kCFRunLoopRunHandledSource
|
||||
|| m_processEvents.processedPostedEvents
|
||||
|
|
@ -316,15 +310,15 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag
|
|||
// immediately, since it has already been exited.
|
||||
|
||||
if (!currentEventLoop()->isRunning()) {
|
||||
qEventDispatcherDebug() << "Top level event loop was exited";
|
||||
qCDebug(lcEventDispatcher) << "Top level event loop was exited";
|
||||
break;
|
||||
} else {
|
||||
qEventDispatcherDebug() << "Top level event loop still running, making another pass";
|
||||
qCDebug(lcEventDispatcher) << "Top level event loop still running, making another pass";
|
||||
}
|
||||
} else {
|
||||
// We were called manually, through processEvents(), and should stop processing
|
||||
// events, even if we didn't finish processing all the queued events.
|
||||
qEventDispatcherDebug() << "Top level processEvents was interrupted";
|
||||
qCDebug(lcEventDispatcher) << "Top level processEvents was interrupted";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -353,7 +347,7 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag
|
|||
// date in the past (overdue) will fire on the next run loop pass. The Qt
|
||||
// APIs on the other hand document eg. zero-interval timers to always be
|
||||
// handled after processing all available window-system events.
|
||||
qEventDispatcherDebug() << "Manually processing timers due to overdue timer";
|
||||
qCDebug(lcEventDispatcher) << "Manually processing timers due to overdue timer";
|
||||
processTimers(0);
|
||||
eventsProcessed = true;
|
||||
}
|
||||
|
|
@ -372,7 +366,7 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag
|
|||
|
||||
if (m_processEvents.deferredWakeUp) {
|
||||
m_postedEventsRunLoopSource.signal();
|
||||
qEventDispatcherDebug() << "Processed deferred wake-up";
|
||||
qCDebug(lcEventDispatcher) << "Processed deferred wake-up";
|
||||
}
|
||||
|
||||
bool wasInterrupted = m_processEvents.wasInterrupted;
|
||||
|
|
@ -385,11 +379,11 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag
|
|||
// others below it (eg, in the case of nested event loops). We need to trigger
|
||||
// another interrupt so that the parent processEvents call has a chance to check
|
||||
// if it should continue.
|
||||
qEventDispatcherDebug() << "Forwarding interrupt in case of nested processEvents";
|
||||
qCDebug(lcEventDispatcher) << "Forwarding interrupt in case of nested processEvents";
|
||||
interrupt();
|
||||
}
|
||||
|
||||
qEventDispatcherDebug() << "Returning with eventsProcessed = " << eventsProcessed; qUnIndent();
|
||||
qCDebug(lcEventDispatcher) << "Returning with eventsProcessed =" << eventsProcessed;
|
||||
|
||||
return eventsProcessed;
|
||||
}
|
||||
|
|
@ -397,15 +391,14 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag
|
|||
bool QEventDispatcherCoreFoundation::processPostedEvents()
|
||||
{
|
||||
if (m_processEvents.processedPostedEvents && !(m_processEvents.flags & QEventLoop::EventLoopExec)) {
|
||||
qEventDispatcherDebug() << "Already processed events this pass";
|
||||
qCDebug(lcEventDispatcher) << "Already processed events this pass";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_processEvents.processedPostedEvents = true;
|
||||
|
||||
qEventDispatcherDebug() << "Sending posted events for " << m_processEvents.flags; qIndent();
|
||||
qCDebug(lcEventDispatcher) << "Sending posted events for" << m_processEvents.flags;
|
||||
QCoreApplication::sendPostedEvents();
|
||||
qUnIndent();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -413,12 +406,12 @@ bool QEventDispatcherCoreFoundation::processPostedEvents()
|
|||
void QEventDispatcherCoreFoundation::processTimers(CFRunLoopTimerRef timer)
|
||||
{
|
||||
if (m_processEvents.processedTimers && !(m_processEvents.flags & QEventLoop::EventLoopExec)) {
|
||||
qEventDispatcherDebug() << "Already processed timers this pass";
|
||||
qCDebug(lcEventDispatcher) << "Already processed timers this pass";
|
||||
m_processEvents.deferredUpdateTimers = true;
|
||||
return;
|
||||
}
|
||||
|
||||
qEventDispatcherDebug() << "CFRunLoopTimer " << timer << " fired, activating Qt timers"; qIndent();
|
||||
qCDebug(lcEventDispatcher) << "CFRunLoopTimer" << timer << "fired, activating Qt timers";
|
||||
|
||||
// Activating Qt timers might recurse into processEvents() if a timer-callback
|
||||
// brings up a new event-loop or tries to processes events manually. Although
|
||||
|
|
@ -436,15 +429,15 @@ void QEventDispatcherCoreFoundation::processTimers(CFRunLoopTimerRef timer)
|
|||
m_blockedRunLoopTimer = previouslyBlockedRunLoopTimer;
|
||||
m_processEvents.processedTimers = true;
|
||||
|
||||
qUnIndent();
|
||||
|
||||
// Now that the timer source is unblocked we may need to schedule it again
|
||||
updateTimers();
|
||||
}
|
||||
|
||||
Q_LOGGING_CATEGORY(lcEventDispatcherActivity, "qt.eventdispatcher.activity")
|
||||
|
||||
void QEventDispatcherCoreFoundation::handleRunLoopActivity(CFRunLoopActivity activity)
|
||||
{
|
||||
qEventDispatcherDebug() << qPrintableActivity(activity);
|
||||
qCDebug(lcEventDispatcherActivity) << "Runloop entered activity" << qPrintableActivity(activity);
|
||||
|
||||
switch (activity) {
|
||||
case kCFRunLoopBeforeWaiting:
|
||||
|
|
@ -463,13 +456,11 @@ void QEventDispatcherCoreFoundation::handleRunLoopActivity(CFRunLoopActivity act
|
|||
case kCFRunLoopAfterWaiting:
|
||||
emit awake();
|
||||
break;
|
||||
#if DEBUG_EVENT_DISPATCHER
|
||||
case kCFRunLoopEntry:
|
||||
case kCFRunLoopBeforeTimers:
|
||||
case kCFRunLoopBeforeSources:
|
||||
case kCFRunLoopExit:
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
|
@ -502,19 +493,19 @@ void QEventDispatcherCoreFoundation::wakeUp()
|
|||
// posted event gets processed on the next processEvents() call, so we flag the
|
||||
// need to do a deferred wake-up.
|
||||
m_processEvents.deferredWakeUp = true;
|
||||
qEventDispatcherDebug() << "Already processed posted events, deferring wakeUp";
|
||||
qCDebug(lcEventDispatcher) << "Already processed posted events, deferring wakeUp";
|
||||
return;
|
||||
}
|
||||
|
||||
m_postedEventsRunLoopSource.signal();
|
||||
CFRunLoopWakeUp(CFRunLoopGetMain());
|
||||
|
||||
qEventDispatcherDebug() << "Signaled posted event run-loop source";
|
||||
qCDebug(lcEventDispatcher) << "Signaled posted event run-loop source";
|
||||
}
|
||||
|
||||
void QEventDispatcherCoreFoundation::interrupt()
|
||||
{
|
||||
qEventDispatcherDebug() << "Marking current processEvent as interrupted";
|
||||
qCDebug(lcEventDispatcher) << "Marking current processEvent as interrupted";
|
||||
m_processEvents.wasInterrupted = true;
|
||||
CFRunLoopStop(CFRunLoopGetMain());
|
||||
}
|
||||
|
|
@ -540,8 +531,8 @@ void QEventDispatcherCoreFoundation::unregisterSocketNotifier(QSocketNotifier *n
|
|||
|
||||
void QEventDispatcherCoreFoundation::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object)
|
||||
{
|
||||
qEventDispatcherDebug() << "id = " << timerId << ", interval = " << interval
|
||||
<< ", type = " << timerType << ", object = " << object;
|
||||
qCDebug(lcEventDispatcherTimers) << "Registering timer with id =" << timerId << "interval =" << interval
|
||||
<< "type =" << timerType << "object =" << object;
|
||||
|
||||
Q_ASSERT(timerId > 0 && interval >= 0 && object);
|
||||
Q_ASSERT(object->thread() == thread() && thread() == QThread::currentThread());
|
||||
|
|
@ -557,7 +548,7 @@ bool QEventDispatcherCoreFoundation::unregisterTimer(int timerId)
|
|||
|
||||
bool returnValue = m_timerInfoList.unregisterTimer(timerId);
|
||||
|
||||
qEventDispatcherDebug() << "id = " << timerId << ", timers left: " << m_timerInfoList.size();
|
||||
qCDebug(lcEventDispatcherTimers) << "Unegistered timer with id =" << timerId << "Timers left:" << m_timerInfoList.size();
|
||||
|
||||
updateTimers();
|
||||
return returnValue;
|
||||
|
|
@ -569,7 +560,7 @@ bool QEventDispatcherCoreFoundation::unregisterTimers(QObject *object)
|
|||
|
||||
bool returnValue = m_timerInfoList.unregisterTimers(object);
|
||||
|
||||
qEventDispatcherDebug() << "object = " << object << ", timers left: " << m_timerInfoList.size();
|
||||
qCDebug(lcEventDispatcherTimers) << "Unegistered timers for object =" << object << "Timers left:" << m_timerInfoList.size();
|
||||
|
||||
updateTimers();
|
||||
return returnValue;
|
||||
|
|
@ -612,16 +603,16 @@ void QEventDispatcherCoreFoundation::updateTimers()
|
|||
});
|
||||
|
||||
CFRunLoopAddTimer(CFRunLoopGetMain(), m_runLoopTimer, kCFRunLoopCommonModes);
|
||||
qEventDispatcherDebug() << "Created new CFRunLoopTimer " << m_runLoopTimer;
|
||||
qCDebug(lcEventDispatcherTimers) << "Created new CFRunLoopTimer" << m_runLoopTimer;
|
||||
|
||||
} else {
|
||||
CFRunLoopTimerSetNextFireDate(m_runLoopTimer, timeToFire);
|
||||
qEventDispatcherDebug() << "Re-scheduled CFRunLoopTimer " << m_runLoopTimer;
|
||||
qCDebug(lcEventDispatcherTimers) << "Re-scheduled CFRunLoopTimer" << m_runLoopTimer;
|
||||
}
|
||||
|
||||
m_overdueTimerScheduled = !timespecToSeconds(tv);
|
||||
|
||||
qEventDispatcherDebug() << "Next timeout in " << tv << " seconds";
|
||||
qCDebug(lcEventDispatcherTimers) << "Next timeout in" << tv << "seconds";
|
||||
|
||||
} else {
|
||||
// No Qt timers are registered, so make sure we're not running any CF timers
|
||||
|
|
@ -637,7 +628,7 @@ void QEventDispatcherCoreFoundation::invalidateTimer()
|
|||
return;
|
||||
|
||||
CFRunLoopTimerInvalidate(m_runLoopTimer);
|
||||
qEventDispatcherDebug() << "Invalidated CFRunLoopTimer " << m_runLoopTimer;
|
||||
qCDebug(lcEventDispatcherTimers) << "Invalidated CFRunLoopTimer" << m_runLoopTimer;
|
||||
|
||||
CFRelease(m_runLoopTimer);
|
||||
m_runLoopTimer = 0;
|
||||
|
|
|
|||
|
|
@ -85,19 +85,22 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#define DEBUG_EVENT_DISPATCHER 0
|
||||
|
||||
#include <QtCore/qabstracteventdispatcher.h>
|
||||
#include <QtCore/private/qtimerinfo_unix_p.h>
|
||||
#include <QtCore/private/qcfsocketnotifier_p.h>
|
||||
#include <QtCore/private/qcore_mac_p.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qloggingcategory.h>
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(RunLoopModeTracker));
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(lcEventDispatcher);
|
||||
Q_DECLARE_LOGGING_CATEGORY(lcEventDispatcherTimers)
|
||||
|
||||
class QEventDispatcherCoreFoundation;
|
||||
|
||||
template <class T = QEventDispatcherCoreFoundation>
|
||||
|
|
@ -269,17 +272,4 @@ private:
|
|||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#if DEBUG_EVENT_DISPATCHER
|
||||
extern uint g_eventDispatcherIndentationLevel;
|
||||
#define qEventDispatcherDebug() qDebug().nospace() \
|
||||
<< qPrintable(QString(QLatin1String("| ")).repeated(g_eventDispatcherIndentationLevel)) \
|
||||
<< __FUNCTION__ << "(): "
|
||||
#define qIndent() ++g_eventDispatcherIndentationLevel
|
||||
#define qUnIndent() --g_eventDispatcherIndentationLevel
|
||||
#else
|
||||
#define qEventDispatcherDebug() QT_NO_QDEBUG_MACRO()
|
||||
#define qIndent()
|
||||
#define qUnIndent()
|
||||
#endif
|
||||
|
||||
#endif // QEVENTDISPATCHER_CF_P_H
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ extern "C" int qt_main_wrapper(int argc, char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
qEventDispatcherDebug() << "Running UIApplicationMain"; qIndent();
|
||||
qCDebug(lcEventDispatcher) << "Running UIApplicationMain";
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([QIOSApplicationDelegate class]));
|
||||
}
|
||||
}
|
||||
|
|
@ -263,7 +263,7 @@ static void __attribute__((noinline, noreturn)) user_main_trampoline()
|
|||
int exitCode = main(argc, argv);
|
||||
delete[] argv;
|
||||
|
||||
qEventDispatcherDebug() << "Returned from main with exit code " << exitCode;
|
||||
qCDebug(lcEventDispatcher) << "Returned from main with exit code " << exitCode;
|
||||
|
||||
if (Q_UNLIKELY(debugStackUsage))
|
||||
userMainStack.printUsage();
|
||||
|
|
@ -322,7 +322,7 @@ static bool rootLevelRunLoopIntegration()
|
|||
|
||||
+ (void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||
{
|
||||
qCDebug(lcQpaApplication) << "Application launched with options" << notification.userInfo;
|
||||
qCDebug(lcEventDispatcher) << "Application launched with options" << notification.userInfo;
|
||||
|
||||
if (!isQtApplication())
|
||||
return;
|
||||
|
|
@ -331,7 +331,7 @@ static bool rootLevelRunLoopIntegration()
|
|||
// We schedule the main-redirection for the next run-loop pass, so that we
|
||||
// can return from this function and let UIApplicationMain finish its job.
|
||||
// This results in running Qt's application eventloop as a nested runloop.
|
||||
qCDebug(lcQpaApplication) << "Scheduling main() on next run-loop pass";
|
||||
qCDebug(lcEventDispatcher) << "Scheduling main() on next run-loop pass";
|
||||
CFRunLoopTimerRef userMainTimer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault,
|
||||
CFAbsoluteTimeGetCurrent(), 0, 0, 0, ^(CFRunLoopTimerRef) { user_main_trampoline(); });
|
||||
CFRunLoopAddTimer(CFRunLoopGetMain(), userMainTimer, kCFRunLoopCommonModes);
|
||||
|
|
@ -339,10 +339,10 @@ static bool rootLevelRunLoopIntegration()
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
switch (setjmp(processEventEnterJumpPoint)) {
|
||||
case kJumpPointSetSuccessfully:
|
||||
qCDebug(lcQpaApplication) << "Running main() on separate stack"; qIndent();
|
||||
|
||||
qCDebug(lcEventDispatcher) << "Running main() on separate stack";
|
||||
// Redirect the stack pointer to the start of the reserved stack. This ensures
|
||||
// that when we longjmp out of the event dispatcher and continue execution, the
|
||||
// 'Qt main' call-stack will not be smashed, as it lives in a part of the stack
|
||||
|
|
@ -360,7 +360,7 @@ static bool rootLevelRunLoopIntegration()
|
|||
case kJumpedFromEventDispatcherProcessEvents:
|
||||
// We've returned from the longjmp in the event dispatcher,
|
||||
// and the stack has been restored to its old self.
|
||||
qUnIndent(); qCDebug(lcQpaApplication) << "Returned from processEvents";
|
||||
qCDebug(lcEventDispatcher) << "↳ Jumped from processEvents due to exec";
|
||||
|
||||
if (Q_UNLIKELY(debugStackUsage))
|
||||
userMainStack.printUsage();
|
||||
|
|
@ -396,18 +396,18 @@ static const char kApplicationWillTerminateExitCode = char(SIGTERM | 0x80);
|
|||
applicationAboutToTerminate = true;
|
||||
switch (setjmp(applicationWillTerminateJumpPoint)) {
|
||||
case kJumpPointSetSuccessfully:
|
||||
qEventDispatcherDebug() << "Exiting qApp with SIGTERM exit code"; qIndent();
|
||||
qCDebug(lcEventDispatcher) << "Exiting qApp with SIGTERM exit code";
|
||||
qApp->exit(kApplicationWillTerminateExitCode);
|
||||
|
||||
// The runloop will not exit when the application is about to terminate,
|
||||
// so we'll never see the exit activity and have a chance to return from
|
||||
// QEventLoop::exec(). We initiate the return manually as a workaround.
|
||||
qEventDispatcherDebug() << "Manually triggering return from event loop exec";
|
||||
qCDebug(lcEventDispatcher) << "Manually triggering return from event loop exec";
|
||||
static_cast<QIOSEventDispatcher *>(qApp->eventDispatcher())->interruptEventLoopExec();
|
||||
break;
|
||||
case kJumpedFromUserMainTrampoline:
|
||||
// The user's main has returned, so we're ready to let iOS terminate the application
|
||||
qUnIndent(); qEventDispatcherDebug() << "kJumpedFromUserMainTrampoline, allowing iOS to terminate";
|
||||
qCDebug(lcEventDispatcher) << "kJumpedFromUserMainTrampoline, allowing iOS to terminate";
|
||||
break;
|
||||
default:
|
||||
qFatal("Unexpected jump result in event loop integration");
|
||||
|
|
@ -434,13 +434,15 @@ bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoo
|
|||
return QEventDispatcherCoreFoundation::processEvents(flags);
|
||||
|
||||
if (applicationAboutToTerminate) {
|
||||
qEventDispatcherDebug() << "Detected QEventLoop exec after application termination";
|
||||
qCDebug(lcEventDispatcher) << "Detected QEventLoop exec after application termination";
|
||||
// Re-issue exit, and return immediately
|
||||
qApp->exit(kApplicationWillTerminateExitCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_processEventLevel && (flags & QEventLoop::EventLoopExec)) {
|
||||
qCDebug(lcEventDispatcher) << "Processing events with flags" << flags;
|
||||
|
||||
++m_processEventLevel;
|
||||
|
||||
m_runLoopExitObserver.addToMode(kCFRunLoopCommonModes);
|
||||
|
|
@ -449,7 +451,7 @@ bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoo
|
|||
// is asked to exit, so that we can return from QEventLoop::exec().
|
||||
switch (setjmp(processEventExitJumpPoint)) {
|
||||
case kJumpPointSetSuccessfully:
|
||||
qEventDispatcherDebug() << "QEventLoop exec detected, jumping back to native runloop";
|
||||
qCDebug(lcEventDispatcher) << "QEventLoop exec detected, jumping back to system runloop ↵";
|
||||
longjmp(processEventEnterJumpPoint, kJumpedFromEventDispatcherProcessEvents);
|
||||
break;
|
||||
case kJumpedFromEventLoopExecInterrupt:
|
||||
|
|
@ -457,7 +459,7 @@ bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoo
|
|||
// signal), and we jumped back though processEventExitJumpPoint. We return from processEvents,
|
||||
// which will emit aboutToQuit if it's QApplication's event loop, and then return to the user's
|
||||
// main, which can do whatever it wants, including calling exec() on the application again.
|
||||
qEventDispatcherDebug() << "kJumpedFromEventLoopExecInterrupt, returning with eventsProcessed = true";
|
||||
qCDebug(lcEventDispatcher) << "⇢ System runloop exited, returning with eventsProcessed = true";
|
||||
return true;
|
||||
default:
|
||||
qFatal("Unexpected jump result in event loop integration");
|
||||
|
|
@ -485,9 +487,8 @@ bool QIOSEventDispatcher::processPostedEvents()
|
|||
if (!QEventDispatcherCoreFoundation::processPostedEvents())
|
||||
return false;
|
||||
|
||||
qEventDispatcherDebug() << "Sending window system events for " << m_processEvents.flags; qIndent();
|
||||
qCDebug(lcEventDispatcher) << "Sending window system events for" << m_processEvents.flags;
|
||||
QWindowSystemInterface::sendWindowSystemEvents(m_processEvents.flags);
|
||||
qUnIndent();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -497,10 +498,8 @@ void QIOSEventDispatcher::handleRunLoopExit(CFRunLoopActivity activity)
|
|||
Q_UNUSED(activity);
|
||||
Q_ASSERT(activity == kCFRunLoopExit);
|
||||
|
||||
if (m_processEventLevel == 1 && !currentEventLoop()->isRunning()) {
|
||||
qEventDispatcherDebug() << "Root runloop level exited";
|
||||
if (m_processEventLevel == 1 && !currentEventLoop()->isRunning())
|
||||
interruptEventLoopExec();
|
||||
}
|
||||
}
|
||||
|
||||
void QIOSEventDispatcher::interruptEventLoopExec()
|
||||
|
|
@ -516,12 +515,12 @@ void QIOSEventDispatcher::interruptEventLoopExec()
|
|||
// processEvents, instead of back in didFinishLaunchingWithOptions.
|
||||
switch (setjmp(processEventEnterJumpPoint)) {
|
||||
case kJumpPointSetSuccessfully:
|
||||
qEventDispatcherDebug() << "Jumping back to processEvents";
|
||||
qCDebug(lcEventDispatcher) << "Jumping into processEvents due to system runloop exit ⇢";
|
||||
longjmp(processEventExitJumpPoint, kJumpedFromEventLoopExecInterrupt);
|
||||
break;
|
||||
case kJumpedFromEventDispatcherProcessEvents:
|
||||
// QEventLoop was re-executed
|
||||
qEventDispatcherDebug() << "kJumpedFromEventDispatcherProcessEvents";
|
||||
qCDebug(lcEventDispatcher) << "↳ Jumped from processEvents due to re-exec";
|
||||
break;
|
||||
default:
|
||||
qFatal("Unexpected jump result in event loop integration");
|
||||
|
|
|
|||
Loading…
Reference in New Issue