8f427b2 by axis at 2009-04-24 1
/****************************************************************************
2
**
89c08c0 by Jason McDonald at 2012-01-11 3
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
04e3b30 by Jason McDonald at 2009-09-09 4
** All rights reserved.
da8dc76 by axis at 2009-08-06 5
** Contact: Nokia Corporation (qt-info@nokia.com)
8f427b2 by axis at 2009-04-24 6
**
bec7a9c by Jason McDonald at 2009-10-06 7
** This file is part of the QtCore module of the Qt Toolkit.
8f427b2 by axis at 2009-04-24 8
**
a014c07 by axis at 2009-06-03 9
** $QT_BEGIN_LICENSE:LGPL$
10
** GNU Lesser General Public License Usage
1eea52e by Jyri Tahtela at 2011-05-13 11
** This file may be used under the terms of the GNU Lesser General Public
12
** License version 2.1 as published by the Free Software Foundation and
13
** appearing in the file LICENSE.LGPL included in the packaging of this
14
** file. Please review the following information to ensure the GNU Lesser
15
** General Public License version 2.1 requirements will be met:
16
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
a014c07 by axis at 2009-06-03 17
**
04e3b30 by Jason McDonald at 2009-09-09 18
** In addition, as a special exception, Nokia gives you certain additional
1eea52e by Jyri Tahtela at 2011-05-13 19
** rights. These rights are described in the Nokia Qt LGPL Exception
04e3b30 by Jason McDonald at 2009-09-09 20
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
a014c07 by axis at 2009-06-03 21
**
1eea52e by Jyri Tahtela at 2011-05-13 22
** GNU General Public License Usage
23
** Alternatively, this file may be used under the terms of the GNU General
24
** Public License version 3.0 as published by the Free Software Foundation
25
** and appearing in the file LICENSE.GPL included in the packaging of this
26
** file. Please review the following information to ensure the GNU General
27
** Public License version 3.0 requirements will be met:
28
** http://www.gnu.org/copyleft/gpl.html.
29
**
30
** Other Usage
31
** Alternatively, this file may be used in accordance with the terms and
32
** conditions contained in a signed written agreement between you and Nokia.
115a995 by Jason McDonald at 2009-08-31 33
**
34
**
35
**
36
**
a014c07 by axis at 2009-06-03 37
**
38
** $QT_END_LICENSE$
8f427b2 by axis at 2009-04-24 39
**
40
****************************************************************************/
41
42
#ifndef QEVENTDISPATCHER_SYMBIAN_P_H
43
#define QEVENTDISPATCHER_SYMBIAN_P_H
44
45
//
46
//  W A R N I N G
47
//  -------------
48
//
49
// This file is not part of the Qt API.  It exists purely as an
50
// implementation detail.  This header file may change from version to
51
// version without notice, or even be removed.
52
//
53
// We mean it.
54
//
55
56
#include <qhash.h>
57
#include <qset.h>
58
#include <qshareddata.h>
59
#include <qabstracteventdispatcher.h>
60
#include <private/qabstracteventdispatcher_p.h>
61
#include <qthread.h>
62
#include <qmutex.h>
63
#include <qwaitcondition.h>
64
#include <qsocketnotifier.h>
99dbc23 by mread at 2010-04-22 65
#include <qdatetime.h>
08ec37f by mread at 2011-02-03 66
#include <qelapsedtimer.h>
8f427b2 by axis at 2009-04-24 67
68
#include <e32base.h>
69
70
#include <sys/types.h>
71
#include <sys/socket.h>
72
#include <sys/select.h>
73
74
QT_BEGIN_NAMESPACE
75
76
77
class QEventDispatcherSymbian;
78
class QTimerActiveObject;
79
1adef92 by Shane Kearns at 2011-03-17 80
class Q_CORE_EXPORT QActiveObject : public CActive
dbf64e8 by axis at 2009-05-19 81
{
82
public:
83
    QActiveObject(TInt priority, QEventDispatcherSymbian *dispatcher);
84
    ~QActiveObject();
85
1adef92 by Shane Kearns at 2011-03-17 86
    bool maybeDeferSocketEvent();
5f5119e by mread at 2011-11-08 87
    bool maybeQueueForLater();
dbf64e8 by axis at 2009-05-19 88
    void reactivateAndComplete();
89
protected:
90
    QEventDispatcherSymbian *m_dispatcher;
4490850 by Murray Read at 2012-02-08 91
    QThreadData *m_threadData;
5f5119e by mread at 2011-11-08 92
93
private:
94
    bool m_hasAlreadyRun : 1;
95
    bool m_hasRunAgain : 1;
96
    int m_iterationCount;
dbf64e8 by axis at 2009-05-19 97
};
98
8b55d84 by mread at 2011-06-01 99
class QWakeUpActiveObject : public CActive
8f427b2 by axis at 2009-04-24 100
{
101
public:
102
    QWakeUpActiveObject(QEventDispatcherSymbian *dispatcher);
103
    ~QWakeUpActiveObject();
104
105
    void Complete();
106
107
protected:
108
    void DoCancel();
109
    void RunL();
6f1efe7 by mread at 2011-04-12 110
111
private:
8b55d84 by mread at 2011-06-01 112
    QEventDispatcherSymbian *m_dispatcher;
6f1efe7 by mread at 2011-04-12 113
    TThreadId m_hostThreadId;
8f427b2 by axis at 2009-04-24 114
};
115
116
struct SymbianTimerInfo : public QSharedData
117
{
41a83e1 by Harald Fernengel at 2009-08-03 118
    SymbianTimerInfo();
8f427b2 by axis at 2009-04-24 119
    ~SymbianTimerInfo();
120
121
    int timerId;
122
    int interval;
504dd08 by Shane Kearns at 2009-09-16 123
    int msLeft;
8f427b2 by axis at 2009-04-24 124
    bool inTimerEvent;
125
    QObject *receiver;
126
    QTimerActiveObject *timerAO;
127
    QEventDispatcherSymbian *dispatcher;
128
};
129
130
typedef QExplicitlySharedDataPointer<SymbianTimerInfo> SymbianTimerInfoPtr;
131
132
// This is a bit of a proxy class. See comments in SetActive and Start for details.
5f5119e by mread at 2011-11-08 133
class QTimerActiveObject : public QActiveObject
8f427b2 by axis at 2009-04-24 134
{
135
public:
dbf64e8 by axis at 2009-05-19 136
    QTimerActiveObject(QEventDispatcherSymbian *dispatcher, SymbianTimerInfo *timerInfo);
8f427b2 by axis at 2009-04-24 137
    ~QTimerActiveObject();
138
139
    void Start();
140
141
protected:
142
    void DoCancel();
143
    void RunL();
715db7c by mread at 2009-06-18 144
7604f80 by Robert Griebl at 2009-06-10 145
private:
146
    void Run();
504dd08 by Shane Kearns at 2009-09-16 147
    void StartTimer();
8f427b2 by axis at 2009-04-24 148
149
private:
150
    SymbianTimerInfo *m_timerInfo;
be4d738 by mread at 2011-04-20 151
    QElapsedTimer m_timeoutTimer;
152
    int m_expectedTimeSinceLastEvent;
8f427b2 by axis at 2009-04-24 153
    RTimer m_rTimer;
154
};
155
5f5119e by mread at 2011-11-08 156
class QCompleteDeferredAOs : public CActive
157
{
158
public:
159
    QCompleteDeferredAOs(QEventDispatcherSymbian *dispatcher);
160
    ~QCompleteDeferredAOs();
161
162
    void complete();
163
164
protected:
165
    void DoCancel();
166
    void RunL();
167
168
private:
169
    QEventDispatcherSymbian *m_dispatcher;
170
};
171
dbf64e8 by axis at 2009-05-19 172
class QSocketActiveObject : public QActiveObject
8f427b2 by axis at 2009-04-24 173
{
174
public:
175
    QSocketActiveObject(QEventDispatcherSymbian *dispatcher, QSocketNotifier *notifier);
176
    ~QSocketActiveObject();
177
178
    void deleteLater();
179
180
protected:
181
    void DoCancel();
182
    void RunL();
1adef92 by Shane Kearns at 2011-03-17 183
    void run();
8f427b2 by axis at 2009-04-24 184
185
private:
186
    QSocketNotifier *m_notifier;
187
    bool m_inSocketEvent;
188
    bool m_deleteLater;
189
190
    friend class QEventDispatcherSymbian;
191
};
192
193
class QSelectThread : public QThread
194
{
e5800dd by Harald Fernengel at 2009-08-06 195
    Q_DECLARE_PRIVATE(QThread)
8f427b2 by axis at 2009-04-24 196
197
public:
198
    QSelectThread();
199
    ~QSelectThread();
200
201
    void requestSocketEvents ( QSocketNotifier *notifier, TRequestStatus *status );
202
    void cancelSocketEvents ( QSocketNotifier *notifier );
203
    void restart();
204
    void stop();
205
206
protected:
207
    void run();
208
209
private:
210
    int updateSocketSet(QSocketNotifier::Type type, fd_set *fds);
211
    void updateActivatedNotifiers(QSocketNotifier::Type type, fd_set *fds);
212
213
private:
214
    int m_pipeEnds[2];
215
    QHash<QSocketNotifier *, TRequestStatus *> m_AOStatuses;
216
    QMutex m_mutex;
217
    QWaitCondition m_waitCond;
218
    bool m_quit;
219
};
220
715db7c by mread at 2009-06-18 221
class Q_CORE_EXPORT CQtActiveScheduler : public CActiveScheduler
7f874fe by mread at 2009-06-18 222
{
715db7c by mread at 2009-06-18 223
public: // from CActiveScheduler
224
    virtual void Error(TInt aError) const;
7f874fe by mread at 2009-06-18 225
};
715db7c by mread at 2009-06-18 226
8f427b2 by axis at 2009-04-24 227
class Q_CORE_EXPORT QEventDispatcherSymbian : public QAbstractEventDispatcher
228
{
e4c60e6 by Denis Dzyubenko at 2010-05-03 229
    Q_OBJECT
e5800dd by Harald Fernengel at 2009-08-06 230
    Q_DECLARE_PRIVATE(QAbstractEventDispatcher)
8f427b2 by axis at 2009-04-24 231
232
public:
233
    QEventDispatcherSymbian(QObject *parent = 0);
234
    ~QEventDispatcherSymbian();
235
236
    void flush();
237
    bool hasPendingEvents();
238
    void interrupt();
239
    bool processEvents ( QEventLoop::ProcessEventsFlags flags );
240
    void registerSocketNotifier ( QSocketNotifier * notifier );
241
    void registerTimer ( int timerId, int interval, QObject * object );
242
    QList<TimerInfo> registeredTimers ( QObject * object ) const;
243
    void unregisterSocketNotifier ( QSocketNotifier * notifier );
244
    bool unregisterTimer ( int timerId );
245
    bool unregisterTimers ( QObject * object );
246
    void wakeUp();
247
248
    void startingUp();
249
    void closingDown();
250
a13b2a2 by Murray Read at 2012-02-09 251
    void timerFired(int timerId, QTimerActiveObject *ao);
252
    void wakeUpWasCalled(QWakeUpActiveObject *ao);
8f427b2 by axis at 2009-04-24 253
    void reactivateSocketNotifier(QSocketNotifier *notifier);
dbf64e8 by axis at 2009-05-19 254
5f5119e by mread at 2011-11-08 255
    void addDeferredActiveObject(QActiveObject *object);
256
    void removeDeferredActiveObject(QActiveObject *object);
257
    void queueDeferredActiveObjectsCompletion();
258
    // Can be overridden to activate local active objects too, but do call baseclass!
259
    virtual void reactivateDeferredActiveObjects();
a1db305 by axis at 2009-05-19 260
    inline int iterationCount() const { return m_iterationCount; }
261
1adef92 by Shane Kearns at 2011-03-17 262
    void addDeferredSocketActiveObject(QActiveObject *object);
263
    inline bool areSocketEventsBlocked() const { return m_noSocketEvents; }
264
8f427b2 by axis at 2009-04-24 265
    static void RequestComplete(TRequestStatus *&status, TInt reason);
266
    static void RequestComplete(RThread &threadHandle, TRequestStatus *&status, TInt reason);
267
bd5dfa8 by mread at 2011-11-21 268
    void activeObjectError(int error);
269
8f427b2 by axis at 2009-04-24 270
private:
271
    bool sendPostedEvents();
272
    bool sendDeferredSocketEvents();
273
2b55d52 by Shane Kearns at 2010-04-20 274
    QSelectThread& selectThread();
8f427b2 by axis at 2009-04-24 275
private:
2b55d52 by Shane Kearns at 2010-04-20 276
    QSelectThread *m_selectThread;
8f427b2 by axis at 2009-04-24 277
715db7c by mread at 2009-06-18 278
    CQtActiveScheduler *m_activeScheduler;
8f427b2 by axis at 2009-04-24 279
280
    QHash<int, SymbianTimerInfoPtr> m_timerList;
281
    QHash<QSocketNotifier *, QSocketActiveObject *> m_notifiers;
282
283
    QWakeUpActiveObject *m_wakeUpAO;
5f5119e by mread at 2011-11-08 284
    QCompleteDeferredAOs *m_completeDeferredAOs;
8f427b2 by axis at 2009-04-24 285
286
    volatile bool m_interrupt;
287
    QAtomicInt m_wakeUpDone;
288
a1db305 by axis at 2009-05-19 289
    unsigned char m_iterationCount;
8d8d147 by axis at 2010-09-23 290
    bool m_insideTimerEvent;
8f427b2 by axis at 2009-04-24 291
    bool m_noSocketEvents;
1adef92 by Shane Kearns at 2011-03-17 292
    //deferred until socket events are enabled
293
    QList<QActiveObject *> m_deferredSocketEvents;
dbf64e8 by axis at 2009-05-19 294
5f5119e by mread at 2011-11-08 295
    QList<QActiveObject *> m_deferredActiveObjects;
296
99dbc23 by mread at 2010-04-22 297
    int m_delay;
298
    int m_avgEventTime;
08ec37f by mread at 2011-02-03 299
    QElapsedTimer m_lastIdleRequestTimer;
bd5dfa8 by mread at 2011-11-21 300
    int m_oomErrorCount;
301
    QElapsedTimer m_oomErrorTimer;
8f427b2 by axis at 2009-04-24 302
};
303
cbe647b by axis at 2009-05-15 304
#ifdef QT_DEBUG
8f427b2 by axis at 2009-04-24 305
# define VERIFY_PENDING_REQUEST_STATUS \
e909151 by axis at 2009-08-21 306
    Q_ASSERT(status->Int() == KRequestPending);
8f427b2 by axis at 2009-04-24 307
#else
308
# define VERIFY_PENDING_REQUEST_STATUS
309
#endif
310
311
// Convenience functions for doing some sanity checking on our own complete code.
cbe647b by axis at 2009-05-15 312
// Unless QT_DEBUG is defined, it is exactly equivalent to the Symbian version.
8f427b2 by axis at 2009-04-24 313
inline void QEventDispatcherSymbian::RequestComplete(TRequestStatus *&status, TInt reason)
314
{
315
    VERIFY_PENDING_REQUEST_STATUS
316
    User::RequestComplete(status, reason);
317
}
318
inline void QEventDispatcherSymbian::RequestComplete(RThread &threadHandle, TRequestStatus *&status, TInt reason)
319
{
320
    VERIFY_PENDING_REQUEST_STATUS
321
    threadHandle.RequestComplete(status, reason);
322
}
323
324
#undef VERIFY_PENDING_REQUEST_STATUS
325
326
QT_END_NAMESPACE
327
328
#endif // QEVENTDISPATCHER_SYMBIAN_P_H