From eae8fb85997d82ecec0743ba3e470681129bff41 Mon Sep 17 00:00:00 2001 From: Qt by Nokia Date: Wed, 27 Apr 2011 14:13:26 +0200 Subject: Initial import from qtquick2. Branched from the monolithic repo, Qt qtquick2 branch, at commit a4a585d2ee907746682846ae6e8a48e19deef469 --- src/corelib/animation/qabstractanimation.cpp | 56 +++++++++++++++++++++++++--- src/corelib/animation/qabstractanimation.h | 3 ++ src/corelib/animation/qabstractanimation_p.h | 5 +++ src/corelib/io/qprocess_unix.cpp | 30 +++++++++++++-- src/corelib/kernel/qcoreapplication.cpp | 18 ++++++--- src/corelib/kernel/qcoreapplication.h | 1 + src/corelib/kernel/qcoreapplication_p.h | 2 + 7 files changed, 100 insertions(+), 15 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 602cf8a6fd..f399d7c4cf 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -260,7 +260,8 @@ void QUnifiedTimer::restartAnimationTimer() } else if (!driver->isRunning() || isPauseTimerActive) { driver->start(); isPauseTimerActive = false; - } + } else if (runningLeafAnimations == 0) + driver->stop(); } void QUnifiedTimer::setTimingInterval(int interval) @@ -389,19 +390,49 @@ int QUnifiedTimer::closestPauseAnimationTimeToFinish() return closestTimeToFinish; } + void QUnifiedTimer::installAnimationDriver(QAnimationDriver *d) { - if (driver->isRunning()) { - qWarning("QUnifiedTimer: Cannot change animation driver while animations are running"); + if (driver != &defaultDriver) { + qWarning("QUnifiedTimer: animation driver already installed..."); return; } - if (driver && driver != &defaultDriver) - delete driver; + if (driver->isRunning()) { + driver->stop(); + d->start(); + } driver = d; + +} + + +void QUnifiedTimer::uninstallAnimationDriver(QAnimationDriver *d) +{ + if (driver != d) { + qWarning("QUnifiedTimer: trying to uninstall a driver that is not installed..."); + return; + } + + driver = &defaultDriver; + + if (d->isRunning()) { + d->stop(); + driver->start(); + } } +/*! + Returns true if \a d is the currently installed animation driver + and is not the default animation driver (which can never be uninstalled). +*/ +bool QUnifiedTimer::canUninstallAnimationDriver(QAnimationDriver *d) +{ + return d == driver && driver != &defaultDriver; +} + + /*! \class QAnimationDriver @@ -424,6 +455,12 @@ QAnimationDriver::QAnimationDriver(QAnimationDriverPrivate &dd, QObject *parent) { } +QAnimationDriver::~QAnimationDriver() +{ + QUnifiedTimer *timer = QUnifiedTimer::instance(true); + if (timer->canUninstallAnimationDriver(this)) + uninstall(); +} /*! Advances the animation based on the current time. This function should @@ -453,6 +490,15 @@ void QAnimationDriver::install() timer->installAnimationDriver(this); } +/*! + Uninstalls this animation driver. + */ +void QAnimationDriver::uninstall() +{ + QUnifiedTimer *timer = QUnifiedTimer::instance(true); + timer->uninstallAnimationDriver(this); +} + bool QAnimationDriver::isRunning() const { return d_func()->running; diff --git a/src/corelib/animation/qabstractanimation.h b/src/corelib/animation/qabstractanimation.h index 0900870ce2..a0cb0f93d0 100644 --- a/src/corelib/animation/qabstractanimation.h +++ b/src/corelib/animation/qabstractanimation.h @@ -141,9 +141,12 @@ class Q_CORE_EXPORT QAnimationDriver : public QObject public: QAnimationDriver(QObject *parent = 0); + ~QAnimationDriver(); void advance(); + void install(); + void uninstall(); bool isRunning() const; diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index ba92960f6b..1cba4644a8 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -180,10 +180,15 @@ public: static void updateAnimationTimer(); void installAnimationDriver(QAnimationDriver *driver); + void uninstallAnimationDriver(QAnimationDriver *driver); + bool canUninstallAnimationDriver(QAnimationDriver *driver); void restartAnimationTimer(); void updateAnimationsTime(); + //useful for profiling/debugging + int runningAnimationCount() { return animations.count(); } + protected: void timerEvent(QTimerEvent *); diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 3af9b46df8..f53742b815 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -171,17 +171,27 @@ private: Q_GLOBAL_STATIC(QMutex, processManagerGlobalMutex) -static QProcessManager *processManager() { +static QProcessManager *processManagerInstance = 0; + +static QProcessManager *processManager() +{ // The constructor of QProcessManager should be called only once // so we cannot use Q_GLOBAL_STATIC directly for QProcessManager QMutex *mutex = processManagerGlobalMutex(); QMutexLocker locker(mutex); - static QProcessManager processManager; - return &processManager; + + if (!processManagerInstance) + QProcessPrivate::initializeProcessManager(); + + Q_ASSERT(processManagerInstance); + return processManagerInstance; } QProcessManager::QProcessManager() { + // can only be called from main thread + Q_ASSERT(!qApp || qApp->thread() == QThread::currentThread()); + #if defined (QPROCESS_DEBUG) qDebug() << "QProcessManager::QProcessManager()"; #endif @@ -197,6 +207,8 @@ QProcessManager::QProcessManager() action.sa_handler = qt_sa_sigchld_handler; action.sa_flags = SA_NOCLDSTOP; ::sigaction(SIGCHLD, &action, &qt_sa_old_sigchld_handler); + + processManagerInstance = this; } QProcessManager::~QProcessManager() @@ -221,6 +233,8 @@ QProcessManager::~QProcessManager() if (currentAction.sa_handler == qt_sa_sigchld_handler) { ::sigaction(SIGCHLD, &qt_sa_old_sigchld_handler, 0); } + + processManagerInstance = 0; } void QProcessManager::run() @@ -1287,7 +1301,15 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a void QProcessPrivate::initializeProcessManager() { - (void) processManager(); + if (qApp && qApp->thread() != QThread::currentThread()) { + // The process manager must be initialized in the main thread + // Note: The call below will re-enter this function, but in the right thread, + // so the else statement below will be executed. + QMetaObject::invokeMethod(qApp, "_q_initializeProcessManager", Qt::BlockingQueuedConnection); + } else { + static QProcessManager processManager; + Q_UNUSED(processManager); + } } QT_END_NAMESPACE diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index be86c58d47..e0841cbadc 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -392,6 +392,16 @@ void QCoreApplicationPrivate::createEventDispatcher() #endif } +void QCoreApplicationPrivate::_q_initializeProcessManager() +{ +#ifndef QT_NO_PROCESS +# ifdef Q_OS_UNIX + QProcessPrivate::initializeProcessManager(); +# endif +#endif +} + + QThread *QCoreApplicationPrivate::theMainThread = 0; QThread *QCoreApplicationPrivate::mainThread() { @@ -656,12 +666,6 @@ void QCoreApplication::init() } #endif -#if defined(Q_OS_UNIX) && !(defined(QT_NO_PROCESS)) - // Make sure the process manager thread object is created in the main - // thread. - QProcessPrivate::initializeProcessManager(); -#endif - #ifdef QT_EVAL extern void qt_core_eval_init(uint); qt_core_eval_init(d->application_type); @@ -2728,3 +2732,5 @@ int QCoreApplication::loopLevel() */ QT_END_NAMESPACE + +#include "moc_qcoreapplication.cpp" diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h index 3957158d83..024c5096c9 100644 --- a/src/corelib/kernel/qcoreapplication.h +++ b/src/corelib/kernel/qcoreapplication.h @@ -205,6 +205,7 @@ protected: QCoreApplication(QCoreApplicationPrivate &p); private: + Q_PRIVATE_SLOT(d_func(), void _q_initializeProcessManager()) static bool sendSpontaneousEvent(QObject *receiver, QEvent *event); bool notifyInternal(QObject *receiver, QEvent *event); diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index add2a3553e..fdceab4724 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -85,6 +85,8 @@ public: bool sendThroughObjectEventFilters(QObject *, QEvent *); bool notify_helper(QObject *, QEvent *); + void _q_initializeProcessManager(); + virtual QString appName() const; virtual void createEventDispatcher(); static void removePostedEvent(QEvent *); -- cgit v1.2.3