Base Code merged to SPIN 2.4
[platform/upstream/connman.git] / gdbus / mainloop.c
old mode 100644 (file)
new mode 100755 (executable)
index b8be044..b90a844
@@ -2,7 +2,7 @@
  *
  *  D-Bus helper library
  *
- *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2004-2011  Marcel Holtmann <marcel@holtmann.org>
  *
  *
  *  This program is free software; you can redistribute it and/or modify
 #include <glib.h>
 #include <dbus/dbus.h>
 
-#ifdef NEED_DBUS_WATCH_GET_UNIX_FD
-#define dbus_watch_get_unix_fd dbus_watch_get_fd
-#endif
-
 #include "gdbus.h"
 
-#define DISPATCH_TIMEOUT  0
-
 #define info(fmt...)
 #define error(fmt...)
 #define debug(fmt...)
@@ -74,8 +68,6 @@ static gboolean message_dispatch(void *data)
 {
        DBusConnection *conn = data;
 
-       dbus_connection_ref(conn);
-
        /* Dispatch messages */
        while (dbus_connection_dispatch(conn) == DBUS_DISPATCH_DATA_REMAINS);
 
@@ -88,24 +80,30 @@ static inline void queue_dispatch(DBusConnection *conn,
                                                DBusDispatchStatus status)
 {
        if (status == DBUS_DISPATCH_DATA_REMAINS)
-               g_timeout_add(DISPATCH_TIMEOUT, message_dispatch, conn);
+               g_idle_add(message_dispatch, dbus_connection_ref(conn));
 }
 
 static gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data)
 {
        struct watch_info *info = data;
        unsigned int flags = 0;
-
-       dbus_connection_ref(info->conn);
+       DBusDispatchStatus status;
+       DBusConnection *conn;
 
        if (cond & G_IO_IN)  flags |= DBUS_WATCH_READABLE;
        if (cond & G_IO_OUT) flags |= DBUS_WATCH_WRITABLE;
        if (cond & G_IO_HUP) flags |= DBUS_WATCH_HANGUP;
        if (cond & G_IO_ERR) flags |= DBUS_WATCH_ERROR;
 
+       /* Protect connection from being destroyed by dbus_watch_handle */
+       conn = dbus_connection_ref(info->conn);
+
        dbus_watch_handle(info->watch, flags);
 
-       dbus_connection_unref(info->conn);
+       status = dbus_connection_get_dispatch_status(conn);
+       queue_dispatch(conn, status);
+
+       dbus_connection_unref(conn);
 
        return TRUE;
 }
@@ -226,9 +224,6 @@ static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data)
 
 static void remove_timeout(DBusTimeout *timeout, void *data)
 {
-       if (dbus_timeout_get_enabled(timeout))
-               return;
-
        /* will trigger timeout_handler_free() */
        dbus_timeout_set_data(timeout, NULL, NULL);
 }
@@ -262,12 +257,36 @@ static inline void setup_dbus_with_main_loop(DBusConnection *conn)
                                                                NULL, NULL);
 }
 
+static gboolean setup_bus(DBusConnection *conn, const char *name,
+                                               DBusError *error)
+{
+       gboolean result;
+       DBusDispatchStatus status;
+
+       if (name != NULL) {
+               result = g_dbus_request_name(conn, name, error);
+
+               if (error != NULL) {
+                       if (dbus_error_is_set(error) == TRUE)
+                               return FALSE;
+               }
+
+               if (result == FALSE)
+                       return FALSE;
+       }
+
+       setup_dbus_with_main_loop(conn);
+
+       status = dbus_connection_get_dispatch_status(conn);
+       queue_dispatch(conn, status);
+
+       return TRUE;
+}
+
 DBusConnection *g_dbus_setup_bus(DBusBusType type, const char *name,
                                                        DBusError *error)
 {
        DBusConnection *conn;
-       DBusDispatchStatus status;
-       gboolean result;
 
        conn = dbus_bus_get(type, error);
 
@@ -279,24 +298,34 @@ DBusConnection *g_dbus_setup_bus(DBusBusType type, const char *name,
        if (conn == NULL)
                return NULL;
 
-       if (name != NULL) {
-               result = g_dbus_request_name(conn, name, error);
+       if (setup_bus(conn, name, error) == FALSE) {
+               dbus_connection_unref(conn);
+               return NULL;
+       }
 
-               if (error != NULL) {
-                       if (dbus_error_is_set(error) == TRUE)
-                               result = FALSE;
-               }
+       return conn;
+}
 
-               if (result == FALSE) {
-                       dbus_connection_unref(conn);
+DBusConnection *g_dbus_setup_private(DBusBusType type, const char *name,
+                                                       DBusError *error)
+{
+       DBusConnection *conn;
+
+       conn = dbus_bus_get_private(type, error);
+
+       if (error != NULL) {
+               if (dbus_error_is_set(error) == TRUE)
                        return NULL;
-               }
        }
 
-       setup_dbus_with_main_loop(conn);
+       if (conn == NULL)
+               return NULL;
 
-       status = dbus_connection_get_dispatch_status(conn);
-       queue_dispatch(conn, status);
+       if (setup_bus(conn, name, error) == FALSE) {
+               dbus_connection_close(conn);
+               dbus_connection_unref(conn);
+               return NULL;
+       }
 
        return conn;
 }
@@ -314,8 +343,12 @@ gboolean g_dbus_request_name(DBusConnection *connection, const char *name,
                        return FALSE;
        }
 
-       if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
+       if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+               if (error != NULL)
+                       dbus_set_error(error, name, "Name already in use");
+
                return FALSE;
+       }
 
        return TRUE;
 }