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.
--- 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);