src/dbus/qdbusthreaddebug_p.h
changeset 0 1918ee327afb
child 4 3b1da2848fc7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbus/qdbusthreaddebug_p.h	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,230 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDBus module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QDBUSTHREADDEBUG_P_H
+#define QDBUSTHREADDEBUG_P_H
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API.  It exists purely as an
+// implementation detail.  This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#if !defined(QDBUS_THREAD_DEBUG) && defined(QT_BUILD_INTERNAL)
+# define QDBUS_THREAD_DEBUG 1
+#endif
+
+#if QDBUS_THREAD_DEBUG
+QT_BEGIN_NAMESPACE
+typedef void (*qdbusThreadDebugFunc)(int, int, QDBusConnectionPrivate *);
+QDBUS_EXPORT void qdbusDefaultThreadDebug(int, int, QDBusConnectionPrivate *);
+extern QDBUS_EXPORT qdbusThreadDebugFunc qdbusThreadDebug;
+QT_END_NAMESPACE
+#endif
+
+enum ThreadAction {
+    ConnectAction = 0,
+    DisconnectAction = 1,
+    RegisterObjectAction = 2,
+    UnregisterObjectAction = 3,
+    ObjectRegisteredAtAction = 4,
+
+    CloseConnectionAction = 10,
+    ObjectDestroyedAction = 11,
+    RelaySignalAction = 12,
+    HandleObjectCallAction = 13,
+    HandleSignalAction = 14,
+    ConnectRelayAction = 15,
+    DisconnectRelayAction = 16,
+    FindMetaObject1Action = 17,
+    FindMetaObject2Action = 18,
+    RegisterServiceAction = 19,
+    UnregisterServiceAction = 20,
+    UpdateSignalHookOwnerAction = 21,
+    HandleObjectCallPostEventAction = 22,
+    HandleObjectCallSemaphoreAction = 23,
+    DoDispatchAction = 24,
+    SendWithReplyAsyncAction = 25,
+    MessageResultReceivedAction = 26,
+    ActivateSignalAction = 27,
+    PendingCallBlockAction = 28,
+
+    AddTimeoutAction = 50,
+    RealAddTimeoutAction = 51,
+    RemoveTimeoutAction = 52,
+    KillTimerAction = 58,
+    TimerEventAction = 59,
+    AddWatchAction = 60,
+    RemoveWatchAction = 61,
+    ToggleWatchAction = 62,
+    SocketReadAction = 63,
+    SocketWriteAction = 64
+};
+
+struct QDBusLockerBase
+{
+    enum Condition
+    {
+        BeforeLock,
+        AfterLock,
+        BeforeUnlock,
+        AfterUnlock,
+
+        BeforePost,
+        AfterPost,
+        BeforeDeliver,
+        AfterDeliver,
+
+        BeforeAcquire,
+        AfterAcquire,
+        BeforeRelease,
+        AfterRelease
+    };
+
+#if QDBUS_THREAD_DEBUG
+    static inline void reportThreadAction(int action, int condition, QDBusConnectionPrivate *ptr)
+    { if (qdbusThreadDebug) qdbusThreadDebug(action, condition, ptr); }
+#else
+    static inline void reportThreadAction(int, int, QDBusConnectionPrivate *) { }
+#endif
+};
+
+struct QDBusReadLocker: QDBusLockerBase
+{
+    QDBusConnectionPrivate *self;
+    ThreadAction action;
+    inline QDBusReadLocker(ThreadAction a, QDBusConnectionPrivate *s)
+        : self(s), action(a)
+    {
+        reportThreadAction(action, BeforeLock, self);
+        self->lock.lockForRead();
+        reportThreadAction(action, AfterLock, self);
+    }
+
+    inline ~QDBusReadLocker()
+    {
+        reportThreadAction(action, BeforeUnlock, self);
+        self->lock.unlock();
+        reportThreadAction(action, AfterUnlock, self);
+    }
+};
+
+struct QDBusWriteLocker: QDBusLockerBase
+{
+    QDBusConnectionPrivate *self;
+    ThreadAction action;
+    inline QDBusWriteLocker(ThreadAction a, QDBusConnectionPrivate *s)
+        : self(s), action(a)
+    {
+        reportThreadAction(action, BeforeLock, self);
+        self->lock.lockForWrite();
+        reportThreadAction(action, AfterLock, self);
+    }
+
+    inline ~QDBusWriteLocker()
+    {
+        reportThreadAction(action, BeforeUnlock, self);
+        self->lock.unlock();
+        reportThreadAction(action, AfterUnlock, self);
+    }
+};
+
+struct QDBusMutexLocker: QDBusLockerBase
+{
+    QDBusConnectionPrivate *self;
+    QMutex *mutex;
+    ThreadAction action;
+    inline QDBusMutexLocker(ThreadAction a, QDBusConnectionPrivate *s,
+                            QMutex *m)
+        : self(s), mutex(m), action(a)
+    {
+        reportThreadAction(action, BeforeLock, self);
+        mutex->lock();
+        reportThreadAction(action, AfterLock, self);
+    }
+
+    inline ~QDBusMutexLocker()
+    {
+        reportThreadAction(action, BeforeUnlock, self);
+        mutex->unlock();
+        reportThreadAction(action, AfterUnlock, self);
+    }
+};
+
+struct QDBusDispatchLocker: QDBusMutexLocker
+{
+    inline QDBusDispatchLocker(ThreadAction a, QDBusConnectionPrivate *s)
+        : QDBusMutexLocker(a, s, &s->dispatchLock)
+    { }
+};
+
+struct QDBusWatchAndTimeoutLocker: QDBusMutexLocker
+{
+    inline QDBusWatchAndTimeoutLocker(ThreadAction a, QDBusConnectionPrivate *s)
+        : QDBusMutexLocker(a, s, &s->watchAndTimeoutLock)
+    { }
+};
+
+#if QDBUS_THREAD_DEBUG
+# define SEM_ACQUIRE(action, sem)                                       \
+    do {                                                                \
+    QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::BeforeAcquire, this); \
+    sem.acquire();                                                      \
+    QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::AfterAcquire, this); \
+    } while (0)
+
+# define SEM_RELEASE(action, sem)                                       \
+    do {                                                                \
+    QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::BeforeRelease, that); \
+    sem.release();                                                      \
+    QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::AfterRelease, that); \
+    } while (0)
+
+#else
+# define SEM_ACQUIRE(action, sem)       sem.acquire()
+# define SEM_RELEASE(action, sem)       sem.release()
+#endif
+
+#endif