diff options
author | Shane Kearns <shane.kearns@accenture.com> | 2011-10-11 14:51:58 (GMT) |
---|---|---|
committer | Shane Kearns <shane.kearns@accenture.com> | 2011-10-11 14:51:58 (GMT) |
commit | c47cd8f01ea5d3f2a6d0ea73572d9735947919a0 (patch) | |
tree | aac4814b83935c363d260697889b4dfa7fc59933 /src/corelib | |
parent | dde0a87329a9e48f82c16c383a42ce42c5422351 (diff) | |
download | Qt-c47cd8f01ea5d3f2a6d0ea73572d9735947919a0.zip Qt-c47cd8f01ea5d3f2a6d0ea73572d9735947919a0.tar.gz Qt-c47cd8f01ea5d3f2a6d0ea73572d9735947919a0.tar.bz2 |
Symbian - fix deleteLater not working from RunL
deleteLater stores the loop level in the deferred delete event to
prevent the object being deleted by a nested event loop.
However as symbian active object RunL functions are called directly
from the active scheduler, the loop level is incorrect at that point.
(It is normally set by QCoreApplication::notifyInternal)
To solve this, the loop level is adjusted before calling RunIfReady
so that it is correct during RunL functions. It is then adjusted back
for the specific active objects in the event dispatcher that call
into QCoreApplication - sendPostedEvents, sendEvent.
Task-number: QTBUG-21928
Reviewed-by: mread
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_symbian.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp index 5e2bc4f..b796728 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp @@ -61,6 +61,24 @@ QT_BEGIN_NAMESPACE #define NULLTIMER_PRIORITY CActive::EPriorityLow #define COMPLETE_DEFERRED_ACTIVE_OBJECTS_PRIORITY CActive::EPriorityIdle +class Incrementer { + int &variable; +public: + inline Incrementer(int &variable) : variable(variable) + { ++variable; } + inline ~Incrementer() + { --variable; } +}; + +class Decrementer { + int &variable; +public: + inline Decrementer(int &variable) : variable(variable) + { --variable; } + inline ~Decrementer() + { ++variable; } +}; + static inline int qt_pipe_write(int socket, const char *data, qint64 len) { return ::write(socket, data, len); @@ -830,6 +848,8 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla #endif while (1) { + //native active object callbacks are logically part of the event loop, so inc nesting level + Incrementer inc(d->threadData->loopLevel); if (block) { // This is where Qt will spend most of its time. CActiveScheduler::Current()->WaitForAnyRequest(); @@ -894,6 +914,7 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla void QEventDispatcherSymbian::timerFired(int timerId) { + Q_D(QAbstractEventDispatcher); QHash<int, SymbianTimerInfoPtr>::iterator i = m_timerList.find(timerId); if (i == m_timerList.end()) { // The timer has been deleted. Ignore this event. @@ -912,6 +933,8 @@ void QEventDispatcherSymbian::timerFired(int timerId) m_insideTimerEvent = true; QTimerEvent event(timerInfo->timerId); + //undo the added nesting level around RunIfReady, since Qt's event system also nests + Decrementer dec(d->threadData->loopLevel); QCoreApplication::sendEvent(timerInfo->receiver, &event); m_insideTimerEvent = oldInsideTimerEventValue; @@ -922,6 +945,7 @@ void QEventDispatcherSymbian::timerFired(int timerId) void QEventDispatcherSymbian::socketFired(QSocketActiveObject *socketAO) { + Q_D(QAbstractEventDispatcher); if (m_noSocketEvents) { m_deferredSocketEvents.append(socketAO); return; @@ -929,6 +953,8 @@ void QEventDispatcherSymbian::socketFired(QSocketActiveObject *socketAO) QEvent e(QEvent::SockAct); socketAO->m_inSocketEvent = true; + //undo the added nesting level around RunIfReady, since Qt's event system also nests + Decrementer dec(d->threadData->loopLevel); QCoreApplication::sendEvent(socketAO->m_notifier, &e); socketAO->m_inSocketEvent = false; @@ -943,6 +969,7 @@ void QEventDispatcherSymbian::socketFired(QSocketActiveObject *socketAO) void QEventDispatcherSymbian::wakeUpWasCalled() { + Q_D(QAbstractEventDispatcher); // The reactivation should happen in RunL, right before the call to this function. // This is because m_wakeUpDone is the "signal" that the object can be completed // once more. @@ -952,6 +979,8 @@ void QEventDispatcherSymbian::wakeUpWasCalled() // the sendPostedEvents was done, but before the object was ready to be completed // again. This could deadlock the application if there are no other posted events. m_wakeUpDone.fetchAndStoreOrdered(0); + //undo the added nesting level around RunIfReady, since Qt's event system also nests + Decrementer dec(d->threadData->loopLevel); sendPostedEvents(); } |