src/dbus/qdbusconnection_p.h
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtDBus module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 //
       
    43 //  W A R N I N G
       
    44 //  -------------
       
    45 //
       
    46 // This file is not part of the public API.  This header file may
       
    47 // change from version to version without notice, or even be
       
    48 // removed.
       
    49 //
       
    50 // We mean it.
       
    51 //
       
    52 //
       
    53 
       
    54 #ifndef QDBUSCONNECTION_P_H
       
    55 #define QDBUSCONNECTION_P_H
       
    56 
       
    57 #include <qdbuserror.h>
       
    58 #include <qdbusconnection.h>
       
    59 
       
    60 #include <QtCore/qatomic.h>
       
    61 #include <QtCore/qhash.h>
       
    62 #include <QtCore/qmutex.h>
       
    63 #include <QtCore/qobject.h>
       
    64 #include <QtCore/qpointer.h>
       
    65 #include <QtCore/qreadwritelock.h>
       
    66 #include <QtCore/qstringlist.h>
       
    67 #include <QtCore/qvarlengtharray.h>
       
    68 #include <QtCore/qvector.h>
       
    69 
       
    70 #include <qdbus_symbols_p.h>
       
    71 
       
    72 #include <qdbusmessage.h>
       
    73 
       
    74 QT_BEGIN_NAMESPACE
       
    75 
       
    76 class QDBusMessage;
       
    77 class QSocketNotifier;
       
    78 class QTimerEvent;
       
    79 class QDBusObjectPrivate;
       
    80 class QDBusCallDeliveryEvent;
       
    81 class QDBusActivateObjectEvent;
       
    82 class QMetaMethod;
       
    83 class QDBusInterfacePrivate;
       
    84 struct QDBusMetaObject;
       
    85 class QDBusAbstractInterface;
       
    86 class QDBusConnectionInterface;
       
    87 class QDBusPendingCallPrivate;
       
    88 
       
    89 class QDBusErrorInternal
       
    90 {
       
    91     mutable DBusError error;
       
    92     Q_DISABLE_COPY(QDBusErrorInternal)
       
    93 public:
       
    94     inline QDBusErrorInternal() { q_dbus_error_init(&error); }
       
    95     inline ~QDBusErrorInternal() { q_dbus_error_free(&error); }
       
    96     inline bool operator !() const { return !q_dbus_error_is_set(&error); }
       
    97     inline operator DBusError *() { q_dbus_error_free(&error); return &error; }
       
    98     inline operator QDBusError() const { QDBusError err(&error); q_dbus_error_free(&error); return err; }
       
    99 };
       
   100 
       
   101 // QDBusConnectionPrivate holds the DBusConnection and
       
   102 // can have many QDBusConnection objects referring to it
       
   103 
       
   104 class QDBusConnectionPrivate: public QObject
       
   105 {
       
   106     Q_OBJECT
       
   107 public:
       
   108     // structs and enums
       
   109     enum ConnectionMode { InvalidMode, ServerMode, ClientMode, PeerMode }; // LocalMode
       
   110 
       
   111     struct Watcher
       
   112     {
       
   113         Watcher(): watch(0), read(0), write(0) {}
       
   114         DBusWatch *watch;
       
   115         QSocketNotifier *read;
       
   116         QSocketNotifier *write;
       
   117     };
       
   118 
       
   119     struct SignalHook
       
   120     {
       
   121         inline SignalHook() : obj(0), midx(-1) { }
       
   122         QString owner, service, path, signature;
       
   123         QObject* obj;
       
   124         int midx;
       
   125         QList<int> params;
       
   126         QByteArray matchRule;
       
   127     };
       
   128 
       
   129     struct ObjectTreeNode
       
   130     {
       
   131         typedef QVector<ObjectTreeNode> DataList;
       
   132 
       
   133         inline ObjectTreeNode() : obj(0), flags(0) { }
       
   134         inline ObjectTreeNode(const QString &n) // intentionally implicit
       
   135             : name(n), obj(0), flags(0) { }
       
   136         inline ~ObjectTreeNode() { }
       
   137         inline bool operator<(const QString &other) const
       
   138             { return name < other; }
       
   139         inline bool operator<(const QStringRef &other) const
       
   140             { return QStringRef(&name) < other; }
       
   141 
       
   142         QString name;
       
   143         QObject* obj;
       
   144         int flags;
       
   145         DataList children;
       
   146     };
       
   147 
       
   148 public:
       
   149     // typedefs
       
   150     typedef QMultiHash<int, Watcher> WatcherHash;
       
   151     typedef QHash<int, DBusTimeout *> TimeoutHash;
       
   152     typedef QList<QPair<DBusTimeout *, int> > PendingTimeoutList;
       
   153 
       
   154     typedef QMultiHash<QString, SignalHook> SignalHookHash;
       
   155     typedef QHash<QString, QDBusMetaObject* > MetaObjectHash;
       
   156     typedef QHash<QByteArray, int> MatchRefCountHash;
       
   157 
       
   158 public:
       
   159     // public methods are entry points from other objects
       
   160     explicit QDBusConnectionPrivate(QObject *parent = 0);
       
   161     ~QDBusConnectionPrivate();
       
   162     void deleteYourself();
       
   163 
       
   164     void setBusService(const QDBusConnection &connection);
       
   165     void setPeer(DBusConnection *connection, const QDBusErrorInternal &error);
       
   166     void setConnection(DBusConnection *connection, const QDBusErrorInternal &error);
       
   167     void setServer(DBusServer *server, const QDBusErrorInternal &error);
       
   168     void closeConnection();
       
   169 
       
   170     QString getNameOwner(const QString &service);
       
   171 
       
   172     int send(const QDBusMessage &message);
       
   173     QDBusMessage sendWithReply(const QDBusMessage &message, int mode, int timeout = -1);
       
   174     QDBusMessage sendWithReplyLocal(const QDBusMessage &message);
       
   175     QDBusPendingCallPrivate *sendWithReplyAsync(const QDBusMessage &message, int timeout = -1);
       
   176     int sendWithReplyAsync(const QDBusMessage &message, QObject *receiver,
       
   177                            const char *returnMethod, const char *errorMethod, int timeout = -1);
       
   178     void connectSignal(const QString &key, const SignalHook &hook);
       
   179     SignalHookHash::Iterator disconnectSignal(SignalHookHash::Iterator &it);
       
   180     void registerObject(const ObjectTreeNode *node);
       
   181     void connectRelay(const QString &service, const QString &currentOwner,
       
   182                       const QString &path, const QString &interface,
       
   183                       QDBusAbstractInterface *receiver, const char *signal);
       
   184     void disconnectRelay(const QString &service, const QString &currentOwner,
       
   185                          const QString &path, const QString &interface,
       
   186                          QDBusAbstractInterface *receiver, const char *signal);
       
   187 
       
   188     bool handleMessage(const QDBusMessage &msg);
       
   189     void waitForFinished(QDBusPendingCallPrivate *pcall);
       
   190 
       
   191     QDBusMetaObject *findMetaObject(const QString &service, const QString &path,
       
   192                                     const QString &interface, QDBusError &error);
       
   193 
       
   194     void registerService(const QString &serviceName);
       
   195     void unregisterService(const QString &serviceName);
       
   196 
       
   197     void postEventToThread(int action, QObject *target, QEvent *event);
       
   198 
       
   199     inline void serverConnection(const QDBusConnection &connection)
       
   200         { emit newServerConnection(connection); }
       
   201     
       
   202 private:
       
   203     void checkThread();
       
   204     bool handleError(const QDBusErrorInternal &error);
       
   205 
       
   206     void handleSignal(const QString &key, const QDBusMessage &msg);
       
   207     void handleSignal(const QDBusMessage &msg);
       
   208     void handleObjectCall(const QDBusMessage &message);
       
   209 
       
   210     void activateSignal(const SignalHook& hook, const QDBusMessage &msg);
       
   211     void activateObject(ObjectTreeNode &node, const QDBusMessage &msg, int pathStartPos);
       
   212     bool activateInternalFilters(const ObjectTreeNode &node, const QDBusMessage &msg);
       
   213     bool activateCall(QObject *object, int flags, const QDBusMessage &msg);
       
   214 
       
   215     void sendError(const QDBusMessage &msg, QDBusError::ErrorType code);
       
   216     void deliverCall(QObject *object, int flags, const QDBusMessage &msg,
       
   217                      const QList<int> &metaTypes, int slotIdx);
       
   218 
       
   219     bool isServiceRegisteredByThread(const QString &serviceName) const;
       
   220 
       
   221 protected:
       
   222     void customEvent(QEvent *e);
       
   223     void timerEvent(QTimerEvent *e);
       
   224 
       
   225 public slots:
       
   226     // public slots
       
   227     void doDispatch();
       
   228     void socketRead(int);
       
   229     void socketWrite(int);
       
   230     void objectDestroyed(QObject *o);
       
   231     void relaySignal(QObject *obj, const QMetaObject *, int signalId, const QVariantList &args);
       
   232     void _q_serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner);
       
   233 
       
   234 signals:
       
   235     void serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner);
       
   236     void callWithCallbackFailed(const QDBusError &error, const QDBusMessage &message);
       
   237     void newServerConnection(const QDBusConnection &connection);
       
   238 
       
   239 public:
       
   240     QAtomicInt ref;
       
   241     QString name;               // this connection's name
       
   242     QString baseService;        // this connection's base service
       
   243 
       
   244     ConnectionMode mode;
       
   245 
       
   246     // members accessed in unlocked mode (except for deletion)
       
   247     // connection and server provide their own locking mechanisms
       
   248     // busService doesn't have state to be changed
       
   249     DBusConnection *connection;
       
   250     DBusServer *server;
       
   251     QDBusConnectionInterface *busService;
       
   252 
       
   253     // watchers and timeouts are accessed from any thread
       
   254     // but the corresponding timer and QSocketNotifier must be handled
       
   255     // only in the object's thread
       
   256     QMutex watchAndTimeoutLock;
       
   257     WatcherHash watchers;
       
   258     TimeoutHash timeouts;
       
   259     PendingTimeoutList timeoutsPendingAdd;
       
   260 
       
   261     // members accessed through a lock
       
   262     QMutex dispatchLock;
       
   263     QReadWriteLock lock;
       
   264     QDBusError lastError;
       
   265 
       
   266     QStringList serviceNames;
       
   267     SignalHookHash signalHooks;
       
   268     MatchRefCountHash matchRefCounts;
       
   269     ObjectTreeNode rootNode;
       
   270     MetaObjectHash cachedMetaObjects;
       
   271 
       
   272     QMutex callDeliveryMutex;
       
   273     QDBusCallDeliveryEvent *callDeliveryState; // protected by the callDeliveryMutex mutex
       
   274 
       
   275 public:
       
   276     // static methods
       
   277     static int findSlot(QObject *obj, const QByteArray &normalizedName, QList<int>& params);
       
   278     static bool prepareHook(QDBusConnectionPrivate::SignalHook &hook, QString &key,
       
   279                             const QString &service, const QString &owner,
       
   280                             const QString &path, const QString &interface, const QString &name,
       
   281                             QObject *receiver, const char *signal, int minMIdx,
       
   282                             bool buildSignature);
       
   283     static DBusHandlerResult messageFilter(DBusConnection *, DBusMessage *, void *);
       
   284     static QDBusCallDeliveryEvent *prepareReply(QDBusConnectionPrivate *target, QObject *object,
       
   285                                                 int idx, const QList<int> &metaTypes,
       
   286                                                 const QDBusMessage &msg);
       
   287     static void processFinishedCall(QDBusPendingCallPrivate *call);
       
   288 
       
   289     static QDBusConnectionPrivate *d(const QDBusConnection& q) { return q.d; }
       
   290     static QDBusConnection q(QDBusConnectionPrivate *connection) { return QDBusConnection(connection); }
       
   291 
       
   292     static void setSender(const QDBusConnectionPrivate *s);
       
   293     static void setConnection(const QString &name, QDBusConnectionPrivate *c);
       
   294 
       
   295     friend class QDBusActivateObjectEvent;
       
   296     friend class QDBusCallDeliveryEvent;
       
   297 };
       
   298 
       
   299 // in qdbusmisc.cpp
       
   300 extern int qDBusParametersForMethod(const QMetaMethod &mm, QList<int>& metaTypes);
       
   301 extern int qDBusNameToTypeId(const char *name);
       
   302 extern bool qDBusCheckAsyncTag(const char *tag);
       
   303 extern bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name);
       
   304 extern QString qDBusInterfaceFromMetaObject(const QMetaObject *mo);
       
   305 
       
   306 // in qdbusinternalfilters.cpp
       
   307 extern QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node);
       
   308 extern QDBusMessage qDBusPropertyGet(const QDBusConnectionPrivate::ObjectTreeNode &node,
       
   309                                      const QDBusMessage &msg);
       
   310 extern QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNode &node,
       
   311                                      const QDBusMessage &msg);
       
   312 extern QDBusMessage qDBusPropertyGetAll(const QDBusConnectionPrivate::ObjectTreeNode &node,
       
   313                                         const QDBusMessage &msg);
       
   314 
       
   315 QT_END_NAMESPACE
       
   316 
       
   317 #endif