Пример #1
0
bool QEventDispatcherS60::processEvents ( QEventLoop::ProcessEventsFlags flags )
{
    bool ret = false;

    QT_TRY {
        bool oldNoInputEventsValue = m_noInputEvents;
        if (flags & QEventLoop::ExcludeUserInputEvents) {
            m_noInputEvents = true;
        } else {
            m_noInputEvents = false;
            ret = sendDeferredInputEvents() || ret;
        }

        ret = QEventDispatcherSymbian::processEvents(flags) || ret;

        m_noInputEvents = oldNoInputEventsValue;
    } QT_CATCH (const std::exception& ex) {
#ifndef QT_NO_EXCEPTIONS
        CActiveScheduler::Current()->Error(qt_symbian_exception2Error(ex));
#endif
    }
Пример #2
0
bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags flags )
{
    bool handledAnyEvent = false;
    bool oldNoSocketEventsValue = m_noSocketEvents;
    bool oldInsideTimerEventValue = m_insideTimerEvent;

    m_insideTimerEvent = false;

    QT_TRY {
        Q_D(QAbstractEventDispatcher);

        // It is safe if this counter overflows. The main importance is that each
        // iteration count is different from the last.
        m_iterationCount++;

        RThread &thread = d->threadData->symbian_thread_handle;

        bool block;
        if (flags & QEventLoop::WaitForMoreEvents) {
            block = true;
            emit aboutToBlock();
        } else {
            block = false;
        }

        if (flags & QEventLoop::ExcludeSocketNotifiers) {
            m_noSocketEvents = true;
        } else {
            m_noSocketEvents = false;
            handledAnyEvent = sendDeferredSocketEvents();
        }

        bool handledSymbianEvent = false;
        m_interrupt = false;

#ifdef QT_SYMBIAN_PRIORITY_DROP
        QElapsedTimer eventTimer;
#endif

        while (1) {
            if (block) {
                // This is where Qt will spend most of its time.
                CActiveScheduler::Current()->WaitForAnyRequest();
            } else {
                if (thread.RequestCount() == 0) {
#ifdef QT_SYMBIAN_PRIORITY_DROP
                    if (idleDetectorThread()->hasRun()) {
                        m_lastIdleRequestTimer.start();
                        idleDetectorThread()->kick();
                    } else if (m_lastIdleRequestTimer.elapsed() > maxBusyTime) {
                        User::AfterHighRes(m_delay);
                    }
#endif
                    break;
                }
                // This one should return without delay.
                CActiveScheduler::Current()->WaitForAnyRequest();
            }

#ifdef QT_SYMBIAN_PRIORITY_DROP
            if (idleDetectorThread()->hasRun()) {
                if (m_delay > baseDelay)
                    m_delay -= baseDelay;
                m_lastIdleRequestTimer.start();
                idleDetectorThread()->kick();
            } else if (m_lastIdleRequestTimer.elapsed() > maxBusyTime) {
                User::AfterHighRes(m_delay);
                // allow delay to be up to 1/4 of execution time
                if (!idleDetectorThread()->hasRun() && m_delay*3 < m_avgEventTime)
                    m_delay += baseDelay;
            }
            eventTimer.start();
#endif

            TInt error;
            handledSymbianEvent = CActiveScheduler::RunIfReady(error, KMinTInt);
            if (error) {
                qWarning("CActiveScheduler::RunIfReady() returned error: %i\n", error);
                CActiveScheduler::Current()->Error(error);
            }

#ifdef QT_SYMBIAN_PRIORITY_DROP
            int eventDur = eventTimer.elapsed()*1000;
            // average is calcualted as a 5% decaying exponential average
            m_avgEventTime = (m_avgEventTime * 95 + eventDur * 5) / 100;
#endif

            if (!handledSymbianEvent) {
                qFatal("QEventDispatcherSymbian::processEvents(): Caught Symbian stray signal");
            }
            handledAnyEvent = true;
            if (m_interrupt) {
                break;
            }
            block = false;
        };

        emit awake();
    } QT_CATCH (const std::exception& ex) {
#ifndef QT_NO_EXCEPTIONS
        CActiveScheduler::Current()->Error(qt_symbian_exception2Error(ex));
#endif
    }
bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags flags )
{
    bool handledAnyEvent = false;
    bool oldNoSocketEventsValue = m_noSocketEvents;

    QT_TRY {
        Q_D(QAbstractEventDispatcher);

        // It is safe if this counter overflows. The main importance is that each
        // iteration count is different from the last.
        m_iterationCount++;

        RThread &thread = d->threadData->symbian_thread_handle;

        bool block;
        if (flags & QEventLoop::WaitForMoreEvents) {
            block = true;
            emit aboutToBlock();
        } else {
            block = false;
        }

        if (flags & QEventLoop::ExcludeSocketNotifiers) {
            m_noSocketEvents = true;
        } else {
            m_noSocketEvents = false;
            handledAnyEvent = sendDeferredSocketEvents();
        }

        bool handledSymbianEvent = false;
        m_interrupt = false;

        /*
         * This QTime variable is used to measure the time it takes to finish
         * the event loop. If we take too long in the loop, other processes
         * may be starved and killed. After the first event has completed, we
         * take the current time, and if the remaining events take longer than
         * a preset time, we temporarily lower the priority to force a context
         * switch. For applications that do not take unecessarily long in the
         * event loop, the priority will not be altered.
         */
        QTime time;
        enum {
            FirstRun,
            SubsequentRun,
            TimeStarted
        } timeState = FirstRun;

        TProcessPriority priority;

        while (1) {
            if (block) {
                // This is where Qt will spend most of its time.
                CActiveScheduler::Current()->WaitForAnyRequest();
            } else {
                if (thread.RequestCount() == 0) {
                    break;
                }
                // This one should return without delay.
                CActiveScheduler::Current()->WaitForAnyRequest();
            }

            if (timeState == SubsequentRun) {
                time.start();
                timeState = TimeStarted;
            }

            TInt error;
            handledSymbianEvent = CActiveScheduler::RunIfReady(error, CActive::EPriorityIdle);
            if (error) {
                qWarning("CActiveScheduler::RunIfReady() returned error: %i\n", error);
                CActiveScheduler::Current()->Error(error);
            }

            if (!handledSymbianEvent) {
                qFatal("QEventDispatcherSymbian::processEvents(): Caught Symbian stray signal");
            }
            handledAnyEvent = true;
            if (m_interrupt) {
                break;
            }
            block = false;
            if (timeState == TimeStarted && time.elapsed() > 100) {
                priority = m_processHandle.Priority();
                m_processHandle.SetPriority(EPriorityBackground);
                time.start();
                // Slight chance of race condition in the next lines, but nothing fatal
                // will happen, just wrong priority.
                if (m_processHandle.Priority() == EPriorityBackground) {
                    m_processHandle.SetPriority(priority);
                }
            }
            if (timeState == FirstRun)
                timeState = SubsequentRun;
        };

        emit awake();
    } QT_CATCH (const std::exception& ex) {
#ifndef QT_NO_EXCEPTIONS
        CActiveScheduler::Current()->Error(qt_symbian_exception2Error(ex));
#endif
    }