Bug 884840: Added DBusReplyHandler, r=qdot
authorThomas Zimmermann <tdz@users.sourceforge.net>
Tue, 09 Jul 2013 09:55:08 +0200
changeset 138473 75ff62ef62a826cfe421a7007048ffde9b86446d
parent 138445 f2de2035f0af27c31bd5e3f72c46a9d207119071
child 138474 08607d097c8b4bfa01a61ab1beadc752d7c41e32
push idunknown
push userunknown
push dateunknown
reviewersqdot
bugs884840
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 884840: Added DBusReplyHandler, r=qdot Handler functions for DBus replies sometimes need several data fields or need to keep state over replies for multiple messages. The DBus API itself only allows for a single pointer to user data. The class DBusReplyHandler is a base class for implementing DBus reply- message handlers. Users of DBus can inherit from this class to implement message-specific handlers.
ipc/dbus/DBusUtils.cpp
ipc/dbus/DBusUtils.h
--- a/ipc/dbus/DBusUtils.cpp
+++ b/ipc/dbus/DBusUtils.cpp
@@ -642,10 +642,20 @@ int dbus_returns_uint32(DBusMessage *rep
                              DBUS_TYPE_INVALID)) {
     LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
   }
 
   dbus_message_unref(reply);
   return ret;
 }
 
+void DBusReplyHandler::Callback(DBusMessage* aReply, void* aData)
+{
+  MOZ_ASSERT(aData);
+
+  nsRefPtr<DBusReplyHandler> handler =
+    already_AddRefed<DBusReplyHandler>(static_cast<DBusReplyHandler*>(aData));
+
+  handler->Handle(aReply);
+}
+
 }
 }
--- a/ipc/dbus/DBusUtils.h
+++ b/ipc/dbus/DBusUtils.h
@@ -15,16 +15,17 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
 #ifndef mozilla_ipc_dbus_dbusutils_h__
 #define mozilla_ipc_dbus_dbusutils_h__
 
 #include <dbus/dbus.h>
+#include "mozilla/RefPtr.h"
 #include "mozilla/Scoped.h"
 
 // LOGE and free a D-Bus error
 // Using #define so that __FUNCTION__ resolves usefully
 #define LOG_AND_FREE_DBUS_ERROR_WITH_MSG(err, msg) log_and_free_dbus_error(err, __FUNCTION__, msg);
 #define LOG_AND_FREE_DBUS_ERROR(err) log_and_free_dbus_error(err, __FUNCTION__);
 
 struct DBusMessage;
@@ -45,19 +46,56 @@ public:
     if (mMsg) dbus_message_unref(mMsg);
   }
   operator DBusMessage*() { return mMsg; }
   DBusMessage* get() { return mMsg; }
 private:
   DBusMessage* mMsg;
 };
 
+/**
+ * DBusReplyHandler represents a handler for DBus reply messages. Inherit
+ * from this class and implement the Handle method. The method Callback
+ * should be passed to the DBus send function, with the class instance as
+ * user-data argument.
+ */
+class DBusReplyHandler : public mozilla::RefCounted<DBusReplyHandler>
+{
+public:
+  virtual ~DBusReplyHandler() {
+  }
+
+  /**
+   * Implements a call-back function for DBus. The supplied value for
+   * aData must be a pointer to an instance of DBusReplyHandler.
+   */
+  static void Callback(DBusMessage* aReply, void* aData);
+
+  /**
+   * Call-back method for handling the reply message from DBus.
+   */
+  virtual void Handle(DBusMessage* aReply) = 0;
+
+protected:
+  DBusReplyHandler()
+  {
+  }
+
+  DBusReplyHandler(const DBusReplyHandler& aHandler)
+  {
+  }
+
+  DBusReplyHandler& operator = (const DBusReplyHandler& aRhs)
+  {
+    return *this;
+  }
+};
+
 typedef void (*DBusCallback)(DBusMessage *, void *);
 
-
 void log_and_free_dbus_error(DBusError* err,
                              const char* function,
                              DBusMessage* msg = NULL);
 
 dbus_bool_t dbus_func_send(DBusConnection *aConnection,
                            dbus_uint32_t *aSerial,
                            DBusMessage *aMessage);