Merge remote-tracking branch 'origin/api_changes'
[profile/ivi/qtbase.git] / src / dbus / qdbusthreaddebug_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtDBus module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #ifndef QDBUSTHREADDEBUG_P_H
42 #define QDBUSTHREADDEBUG_P_H
43
44 //
45 //  W A R N I N G
46 //  -------------
47 //
48 // This file is not part of the Qt API.  It exists purely as an
49 // implementation detail.  This header file may change from version to
50 // version without notice, or even be removed.
51 //
52 // We mean it.
53 //
54
55 #include <QtCore/qglobal.h>
56
57 #ifndef QT_NO_DBUS
58
59 #if !defined(QDBUS_THREAD_DEBUG) && defined(QT_BUILD_INTERNAL)
60 # define QDBUS_THREAD_DEBUG 1
61 #endif
62
63 #if QDBUS_THREAD_DEBUG
64 QT_BEGIN_NAMESPACE
65 typedef void (*qdbusThreadDebugFunc)(int, int, QDBusConnectionPrivate *);
66 Q_DBUS_EXPORT void qdbusDefaultThreadDebug(int, int, QDBusConnectionPrivate *);
67 extern Q_DBUS_EXPORT qdbusThreadDebugFunc qdbusThreadDebug;
68 QT_END_NAMESPACE
69 #endif
70
71 enum ThreadAction {
72     ConnectAction = 0,
73     DisconnectAction = 1,
74     RegisterObjectAction = 2,
75     UnregisterObjectAction = 3,
76     ObjectRegisteredAtAction = 4,
77
78     CloseConnectionAction = 10,
79     ObjectDestroyedAction = 11,
80     RelaySignalAction = 12,
81     HandleObjectCallAction = 13,
82     HandleSignalAction = 14,
83     ConnectRelayAction = 15,
84     DisconnectRelayAction = 16,
85     FindMetaObject1Action = 17,
86     FindMetaObject2Action = 18,
87     RegisterServiceAction = 19,
88     UnregisterServiceAction = 20,
89     UpdateSignalHookOwnerAction = 21,
90     HandleObjectCallPostEventAction = 22,
91     HandleObjectCallSemaphoreAction = 23,
92     DoDispatchAction = 24,
93     SendWithReplyAsyncAction = 25,
94     MessageResultReceivedAction = 26,
95     ActivateSignalAction = 27,
96     PendingCallBlockAction = 28,
97
98     AddTimeoutAction = 50,
99     RealAddTimeoutAction = 51,
100     RemoveTimeoutAction = 52,
101     KillTimerAction = 58,
102     TimerEventAction = 59,
103     AddWatchAction = 60,
104     RemoveWatchAction = 61,
105     ToggleWatchAction = 62,
106     SocketReadAction = 63,
107     SocketWriteAction = 64
108 };
109
110 struct QDBusLockerBase
111 {
112     enum Condition
113     {
114         BeforeLock,
115         AfterLock,
116         BeforeUnlock,
117         AfterUnlock,
118
119         BeforePost,
120         AfterPost,
121         BeforeDeliver,
122         AfterDeliver,
123
124         BeforeAcquire,
125         AfterAcquire,
126         BeforeRelease,
127         AfterRelease
128     };
129
130 #if QDBUS_THREAD_DEBUG
131     static inline void reportThreadAction(int action, int condition, QDBusConnectionPrivate *ptr)
132     { if (qdbusThreadDebug) qdbusThreadDebug(action, condition, ptr); }
133 #else
134     static inline void reportThreadAction(int, int, QDBusConnectionPrivate *) { }
135 #endif
136 };
137
138 struct QDBusReadLocker: QDBusLockerBase
139 {
140     QDBusConnectionPrivate *self;
141     ThreadAction action;
142     inline QDBusReadLocker(ThreadAction a, QDBusConnectionPrivate *s)
143         : self(s), action(a)
144     {
145         reportThreadAction(action, BeforeLock, self);
146         self->lock.lockForRead();
147         reportThreadAction(action, AfterLock, self);
148     }
149
150     inline ~QDBusReadLocker()
151     {
152         reportThreadAction(action, BeforeUnlock, self);
153         self->lock.unlock();
154         reportThreadAction(action, AfterUnlock, self);
155     }
156 };
157
158 struct QDBusWriteLocker: QDBusLockerBase
159 {
160     QDBusConnectionPrivate *self;
161     ThreadAction action;
162     inline QDBusWriteLocker(ThreadAction a, QDBusConnectionPrivate *s)
163         : self(s), action(a)
164     {
165         reportThreadAction(action, BeforeLock, self);
166         self->lock.lockForWrite();
167         reportThreadAction(action, AfterLock, self);
168     }
169
170     inline ~QDBusWriteLocker()
171     {
172         reportThreadAction(action, BeforeUnlock, self);
173         self->lock.unlock();
174         reportThreadAction(action, AfterUnlock, self);
175     }
176 };
177
178 struct QDBusMutexLocker: QDBusLockerBase
179 {
180     QDBusConnectionPrivate *self;
181     QMutex *mutex;
182     ThreadAction action;
183     inline QDBusMutexLocker(ThreadAction a, QDBusConnectionPrivate *s,
184                             QMutex *m)
185         : self(s), mutex(m), action(a)
186     {
187         reportThreadAction(action, BeforeLock, self);
188         mutex->lock();
189         reportThreadAction(action, AfterLock, self);
190     }
191
192     inline ~QDBusMutexLocker()
193     {
194         reportThreadAction(action, BeforeUnlock, self);
195         mutex->unlock();
196         reportThreadAction(action, AfterUnlock, self);
197     }
198 };
199
200 struct QDBusDispatchLocker: QDBusMutexLocker
201 {
202     inline QDBusDispatchLocker(ThreadAction a, QDBusConnectionPrivate *s)
203         : QDBusMutexLocker(a, s, &s->dispatchLock)
204     { }
205 };
206
207 struct QDBusWatchAndTimeoutLocker: QDBusMutexLocker
208 {
209     inline QDBusWatchAndTimeoutLocker(ThreadAction a, QDBusConnectionPrivate *s)
210         : QDBusMutexLocker(a, s, &s->watchAndTimeoutLock)
211     { }
212 };
213
214 #if QDBUS_THREAD_DEBUG
215 # define SEM_ACQUIRE(action, sem)                                       \
216     do {                                                                \
217     QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::BeforeAcquire, this); \
218     sem.acquire();                                                      \
219     QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::AfterAcquire, this); \
220     } while (0)
221
222 # define SEM_RELEASE(action, sem)                                       \
223     do {                                                                \
224     QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::BeforeRelease, that); \
225     sem.release();                                                      \
226     QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::AfterRelease, that); \
227     } while (0)
228
229 #else
230 # define SEM_ACQUIRE(action, sem)       sem.acquire()
231 # define SEM_RELEASE(action, sem)       sem.release()
232 #endif
233
234 #endif // QT_NO_DBUS
235 #endif