summaryrefslogtreecommitdiffstats
path: root/src/dbus/qdbusconnection_p.h
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit38be0d13830efd2d98281c645c3a60afe05ffece (patch)
tree6ea73f3ec77f7d153333779883e8120f82820abe /src/dbus/qdbusconnection_p.h
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'src/dbus/qdbusconnection_p.h')
-rw-r--r--src/dbus/qdbusconnection_p.h347
1 files changed, 347 insertions, 0 deletions
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
new file mode 100644
index 0000000000..355a6e6d94
--- /dev/null
+++ b/src/dbus/qdbusconnection_p.h
@@ -0,0 +1,347 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the public API. This header file may
+// change from version to version without notice, or even be
+// removed.
+//
+// We mean it.
+//
+//
+
+#ifndef QDBUSCONNECTION_P_H
+#define QDBUSCONNECTION_P_H
+
+#include <qdbuserror.h>
+#include <qdbusconnection.h>
+
+#include <QtCore/qatomic.h>
+#include <QtCore/qhash.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qpointer.h>
+#include <QtCore/qreadwritelock.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qvarlengtharray.h>
+#include <QtCore/qvector.h>
+
+#include "qdbus_symbols_p.h"
+
+#include <qdbusmessage.h>
+
+#ifndef QT_NO_DBUS
+
+QT_BEGIN_NAMESPACE
+
+class QDBusMessage;
+class QSocketNotifier;
+class QTimerEvent;
+class QDBusObjectPrivate;
+class QDBusCallDeliveryEvent;
+class QDBusActivateObjectEvent;
+class QMetaMethod;
+class QDBusInterfacePrivate;
+struct QDBusMetaObject;
+class QDBusAbstractInterface;
+class QDBusConnectionInterface;
+class QDBusPendingCallPrivate;
+
+class QDBusErrorInternal
+{
+ mutable DBusError error;
+ Q_DISABLE_COPY(QDBusErrorInternal)
+public:
+ inline QDBusErrorInternal() { q_dbus_error_init(&error); }
+ inline ~QDBusErrorInternal() { q_dbus_error_free(&error); }
+ inline bool operator !() const { return !q_dbus_error_is_set(&error); }
+ inline operator DBusError *() { q_dbus_error_free(&error); return &error; }
+ inline operator QDBusError() const { QDBusError err(&error); q_dbus_error_free(&error); return err; }
+};
+
+// QDBusConnectionPrivate holds the DBusConnection and
+// can have many QDBusConnection objects referring to it
+
+class QDBusConnectionPrivate: public QObject
+{
+ Q_OBJECT
+public:
+ // structs and enums
+ enum ConnectionMode { InvalidMode, ServerMode, ClientMode, PeerMode }; // LocalMode
+
+ struct Watcher
+ {
+ Watcher(): watch(0), read(0), write(0) {}
+ DBusWatch *watch;
+ QSocketNotifier *read;
+ QSocketNotifier *write;
+ };
+
+ struct SignalHook
+ {
+ inline SignalHook() : obj(0), midx(-1) { }
+ QString service, path, signature;
+ QObject* obj;
+ int midx;
+ QList<int> params;
+ QStringList argumentMatch;
+ QByteArray matchRule;
+ };
+
+ struct ObjectTreeNode
+ {
+ typedef QVector<ObjectTreeNode> DataList;
+
+ inline ObjectTreeNode() : obj(0), flags(0) { }
+ inline ObjectTreeNode(const QString &n) // intentionally implicit
+ : name(n), obj(0), flags(0) { }
+ inline ~ObjectTreeNode() { }
+ inline bool operator<(const QString &other) const
+ { return name < other; }
+ inline bool operator<(const QStringRef &other) const
+ { return QStringRef(&name) < other; }
+
+ QString name;
+ QObject* obj;
+ int flags;
+ DataList children;
+ };
+
+public:
+ // typedefs
+ typedef QMultiHash<int, Watcher> WatcherHash;
+ typedef QHash<int, DBusTimeout *> TimeoutHash;
+ typedef QList<QPair<DBusTimeout *, int> > PendingTimeoutList;
+
+ typedef QMultiHash<QString, SignalHook> SignalHookHash;
+ typedef QHash<QString, QDBusMetaObject* > MetaObjectHash;
+ typedef QHash<QByteArray, int> MatchRefCountHash;
+
+ struct WatchedServiceData {
+ WatchedServiceData() : refcount(0) {}
+ WatchedServiceData(const QString &owner, int refcount = 0)
+ : owner(owner), refcount(refcount)
+ {}
+ QString owner;
+ int refcount;
+ };
+ typedef QHash<QString, WatchedServiceData> WatchedServicesHash;
+
+public:
+ // public methods are entry points from other objects
+ explicit QDBusConnectionPrivate(QObject *parent = 0);
+ ~QDBusConnectionPrivate();
+ void deleteYourself();
+
+ void setBusService(const QDBusConnection &connection);
+ void setPeer(DBusConnection *connection, const QDBusErrorInternal &error);
+ void setConnection(DBusConnection *connection, const QDBusErrorInternal &error);
+ void setServer(DBusServer *server, const QDBusErrorInternal &error);
+ void closeConnection();
+
+ QString getNameOwner(const QString &service);
+
+ int send(const QDBusMessage &message);
+ QDBusMessage sendWithReply(const QDBusMessage &message, int mode, int timeout = -1);
+ QDBusMessage sendWithReplyLocal(const QDBusMessage &message);
+ QDBusPendingCallPrivate *sendWithReplyAsync(const QDBusMessage &message, int timeout = -1);
+ int sendWithReplyAsync(const QDBusMessage &message, QObject *receiver,
+ const char *returnMethod, const char *errorMethod, int timeout = -1);
+ bool connectSignal(const QString &service, const QString &path, const QString& interface,
+ const QString &name, const QStringList &argumentMatch, const QString &signature,
+ QObject *receiver, const char *slot);
+ void connectSignal(const QString &key, const SignalHook &hook);
+ SignalHookHash::Iterator disconnectSignal(SignalHookHash::Iterator &it);
+ bool disconnectSignal(const QString &service, const QString &path, const QString& interface,
+ const QString &name, const QStringList &argumentMatch, const QString &signature,
+ QObject *receiver, const char *slot);
+ void registerObject(const ObjectTreeNode *node);
+ void connectRelay(const QString &service,
+ const QString &path, const QString &interface,
+ QDBusAbstractInterface *receiver, const char *signal);
+ void disconnectRelay(const QString &service,
+ const QString &path, const QString &interface,
+ QDBusAbstractInterface *receiver, const char *signal);
+ void registerService(const QString &serviceName);
+ void unregisterService(const QString &serviceName);
+
+ bool handleMessage(const QDBusMessage &msg);
+ void waitForFinished(QDBusPendingCallPrivate *pcall);
+
+ QDBusMetaObject *findMetaObject(const QString &service, const QString &path,
+ const QString &interface, QDBusError &error);
+
+ void postEventToThread(int action, QObject *target, QEvent *event);
+
+ inline void serverConnection(const QDBusConnection &connection)
+ { emit newServerConnection(connection); }
+
+private:
+ void checkThread();
+ bool handleError(const QDBusErrorInternal &error);
+
+ void handleSignal(const QString &key, const QDBusMessage &msg);
+ void handleSignal(const QDBusMessage &msg);
+ void handleObjectCall(const QDBusMessage &message);
+
+ void activateSignal(const SignalHook& hook, const QDBusMessage &msg);
+ void activateObject(ObjectTreeNode &node, const QDBusMessage &msg, int pathStartPos);
+ bool activateInternalFilters(const ObjectTreeNode &node, const QDBusMessage &msg);
+ bool activateCall(QObject *object, int flags, const QDBusMessage &msg);
+
+ void sendError(const QDBusMessage &msg, QDBusError::ErrorType code);
+ void deliverCall(QObject *object, int flags, const QDBusMessage &msg,
+ const QList<int> &metaTypes, int slotIdx);
+
+ bool isServiceRegisteredByThread(const QString &serviceName) const;
+
+ QString getNameOwnerNoCache(const QString &service);
+
+protected:
+ void customEvent(QEvent *e);
+ void timerEvent(QTimerEvent *e);
+
+public slots:
+ // public slots
+ void doDispatch();
+ void socketRead(int);
+ void socketWrite(int);
+ void objectDestroyed(QObject *o);
+ void relaySignal(QObject *obj, const QMetaObject *, int signalId, const QVariantList &args);
+
+private slots:
+ void serviceOwnerChangedNoLock(const QString &name, const QString &oldOwner, const QString &newOwner);
+ void registerServiceNoLock(const QString &serviceName);
+ void unregisterServiceNoLock(const QString &serviceName);
+
+signals:
+ void serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner);
+ void callWithCallbackFailed(const QDBusError &error, const QDBusMessage &message);
+ void newServerConnection(const QDBusConnection &connection);
+
+public:
+ QAtomicInt ref;
+ QDBusConnection::ConnectionCapabilities capabilities;
+ QString name; // this connection's name
+ QString baseService; // this connection's base service
+
+ ConnectionMode mode;
+
+ // members accessed in unlocked mode (except for deletion)
+ // connection and server provide their own locking mechanisms
+ // busService doesn't have state to be changed
+ DBusConnection *connection;
+ DBusServer *server;
+ QDBusConnectionInterface *busService;
+
+ // watchers and timeouts are accessed from any thread
+ // but the corresponding timer and QSocketNotifier must be handled
+ // only in the object's thread
+ QMutex watchAndTimeoutLock;
+ WatcherHash watchers;
+ TimeoutHash timeouts;
+ PendingTimeoutList timeoutsPendingAdd;
+
+ // members accessed through a lock
+ QMutex dispatchLock;
+ QReadWriteLock lock;
+ QDBusError lastError;
+
+ QStringList serviceNames;
+ WatchedServicesHash watchedServices;
+ SignalHookHash signalHooks;
+ MatchRefCountHash matchRefCounts;
+ ObjectTreeNode rootNode;
+ MetaObjectHash cachedMetaObjects;
+
+ QMutex callDeliveryMutex;
+ QDBusCallDeliveryEvent *callDeliveryState; // protected by the callDeliveryMutex mutex
+
+public:
+ // static methods
+ static int findSlot(QObject *obj, const QByteArray &normalizedName, QList<int>& params);
+ static bool prepareHook(QDBusConnectionPrivate::SignalHook &hook, QString &key,
+ const QString &service,
+ const QString &path, const QString &interface, const QString &name,
+ const QStringList &argMatch,
+ QObject *receiver, const char *signal, int minMIdx,
+ bool buildSignature);
+ static DBusHandlerResult messageFilter(DBusConnection *, DBusMessage *, void *);
+ static bool checkReplyForDelivery(QDBusConnectionPrivate *target, QObject *object,
+ int idx, const QList<int> &metaTypes,
+ const QDBusMessage &msg);
+ static QDBusCallDeliveryEvent *prepareReply(QDBusConnectionPrivate *target, QObject *object,
+ int idx, const QList<int> &metaTypes,
+ const QDBusMessage &msg);
+ static void processFinishedCall(QDBusPendingCallPrivate *call);
+
+ static QDBusConnectionPrivate *d(const QDBusConnection& q) { return q.d; }
+ static QDBusConnection q(QDBusConnectionPrivate *connection) { return QDBusConnection(connection); }
+
+ static void setSender(const QDBusConnectionPrivate *s);
+
+ friend class QDBusActivateObjectEvent;
+ friend class QDBusCallDeliveryEvent;
+};
+
+// in qdbusmisc.cpp
+extern int qDBusParametersForMethod(const QMetaMethod &mm, QList<int>& metaTypes);
+extern int qDBusNameToTypeId(const char *name);
+extern bool qDBusCheckAsyncTag(const char *tag);
+extern bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name);
+extern QString qDBusInterfaceFromMetaObject(const QMetaObject *mo);
+
+// in qdbusinternalfilters.cpp
+extern QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node);
+extern QDBusMessage qDBusPropertyGet(const QDBusConnectionPrivate::ObjectTreeNode &node,
+ const QDBusMessage &msg);
+extern QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNode &node,
+ const QDBusMessage &msg);
+extern QDBusMessage qDBusPropertyGetAll(const QDBusConnectionPrivate::ObjectTreeNode &node,
+ const QDBusMessage &msg);
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_DBUS
+#endif