Skip to content

Commit c47cd8f

Browse files
author
Shane Kearns
committed
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
1 parent dde0a87 commit c47cd8f

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

src/corelib/kernel/qeventdispatcher_symbian.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,24 @@ QT_BEGIN_NAMESPACE
6161
#define NULLTIMER_PRIORITY CActive::EPriorityLow
6262
#define COMPLETE_DEFERRED_ACTIVE_OBJECTS_PRIORITY CActive::EPriorityIdle
6363

64+
class Incrementer {
65+
int &variable;
66+
public:
67+
inline Incrementer(int &variable) : variable(variable)
68+
{ ++variable; }
69+
inline ~Incrementer()
70+
{ --variable; }
71+
};
72+
73+
class Decrementer {
74+
int &variable;
75+
public:
76+
inline Decrementer(int &variable) : variable(variable)
77+
{ --variable; }
78+
inline ~Decrementer()
79+
{ ++variable; }
80+
};
81+
6482
static inline int qt_pipe_write(int socket, const char *data, qint64 len)
6583
{
6684
return ::write(socket, data, len);
@@ -830,6 +848,8 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla
830848
#endif
831849

832850
while (1) {
851+
//native active object callbacks are logically part of the event loop, so inc nesting level
852+
Incrementer inc(d->threadData->loopLevel);
833853
if (block) {
834854
// This is where Qt will spend most of its time.
835855
CActiveScheduler::Current()->WaitForAnyRequest();
@@ -894,6 +914,7 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla
894914

895915
void QEventDispatcherSymbian::timerFired(int timerId)
896916
{
917+
Q_D(QAbstractEventDispatcher);
897918
QHash<int, SymbianTimerInfoPtr>::iterator i = m_timerList.find(timerId);
898919
if (i == m_timerList.end()) {
899920
// The timer has been deleted. Ignore this event.
@@ -912,6 +933,8 @@ void QEventDispatcherSymbian::timerFired(int timerId)
912933
m_insideTimerEvent = true;
913934

914935
QTimerEvent event(timerInfo->timerId);
936+
//undo the added nesting level around RunIfReady, since Qt's event system also nests
937+
Decrementer dec(d->threadData->loopLevel);
915938
QCoreApplication::sendEvent(timerInfo->receiver, &event);
916939

917940
m_insideTimerEvent = oldInsideTimerEventValue;
@@ -922,13 +945,16 @@ void QEventDispatcherSymbian::timerFired(int timerId)
922945

923946
void QEventDispatcherSymbian::socketFired(QSocketActiveObject *socketAO)
924947
{
948+
Q_D(QAbstractEventDispatcher);
925949
if (m_noSocketEvents) {
926950
m_deferredSocketEvents.append(socketAO);
927951
return;
928952
}
929953

930954
QEvent e(QEvent::SockAct);
931955
socketAO->m_inSocketEvent = true;
956+
//undo the added nesting level around RunIfReady, since Qt's event system also nests
957+
Decrementer dec(d->threadData->loopLevel);
932958
QCoreApplication::sendEvent(socketAO->m_notifier, &e);
933959
socketAO->m_inSocketEvent = false;
934960

@@ -943,6 +969,7 @@ void QEventDispatcherSymbian::socketFired(QSocketActiveObject *socketAO)
943969

944970
void QEventDispatcherSymbian::wakeUpWasCalled()
945971
{
972+
Q_D(QAbstractEventDispatcher);
946973
// The reactivation should happen in RunL, right before the call to this function.
947974
// This is because m_wakeUpDone is the "signal" that the object can be completed
948975
// once more.
@@ -952,6 +979,8 @@ void QEventDispatcherSymbian::wakeUpWasCalled()
952979
// the sendPostedEvents was done, but before the object was ready to be completed
953980
// again. This could deadlock the application if there are no other posted events.
954981
m_wakeUpDone.fetchAndStoreOrdered(0);
982+
//undo the added nesting level around RunIfReady, since Qt's event system also nests
983+
Decrementer dec(d->threadData->loopLevel);
955984
sendPostedEvents();
956985
}
957986

0 commit comments

Comments
 (0)