Add first steps of generic task framework
authorMarcel Holtmann <marcel@holtmann.org>
Fri, 7 Aug 2009 18:33:47 +0000 (11:33 -0700)
committerMarcel Holtmann <marcel@holtmann.org>
Fri, 7 Aug 2009 18:33:47 +0000 (11:33 -0700)
include/dbus.h
include/task.h
src/connman.h
src/main.c
src/task.c

index 1a6833b..0593a60 100644 (file)
@@ -37,6 +37,7 @@ extern "C" {
 #define CONNMAN_MANAGER_INTERFACE      CONNMAN_SERVICE ".Manager"
 #define CONNMAN_MANAGER_PATH           "/"
 
+#define CONNMAN_TASK_INTERFACE         CONNMAN_SERVICE ".Task"
 #define CONNMAN_PROFILE_INTERFACE      CONNMAN_SERVICE ".Profile"
 #define CONNMAN_SERVICE_INTERFACE      CONNMAN_SERVICE ".Service"
 #define CONNMAN_DEVICE_INTERFACE       CONNMAN_SERVICE ".Device"
index e31a4c3..dbeb3a7 100644 (file)
@@ -32,6 +32,11 @@ extern "C" {
  * @short_description: Functions for handling tasks
  */
 
+struct connman_task;
+
+struct connman_task *connman_task_create(void);
+void connman_task_destroy(struct connman_task *task);
+
 #ifdef __cplusplus
 }
 #endif
index 39efb97..bbe9e22 100644 (file)
@@ -81,6 +81,9 @@ void __connman_plugin_cleanup(void);
 
 #include <connman/task.h>
 
+int __connman_task_init(void);
+void __connman_task_cleanup(void);
+
 #include <connman/security.h>
 
 int __connman_security_check_privilege(DBusMessage *message,
index ede37a0..3e77472 100644 (file)
@@ -207,6 +207,7 @@ int main(int argc, char *argv[])
        __connman_resolver_init();
        __connman_rtnl_init();
        __connman_udev_init();
+       __connman_task_init();
 
        __connman_plugin_init(option_plugin, option_noplugin);
 
@@ -231,6 +232,7 @@ int main(int argc, char *argv[])
 
        __connman_plugin_cleanup();
 
+       __connman_task_cleanup();
        __connman_udev_cleanup();
        __connman_rtnl_cleanup();
        __connman_resolver_cleanup();
index 97a6592..da94b3f 100644 (file)
 #include <config.h>
 #endif
 
+#include <glib.h>
+
 #include "connman.h"
+
+struct connman_task {
+       char *path;
+       pid_t pid;
+};
+
+static GHashTable *task_hash = NULL;
+
+static volatile gint task_counter;
+
+static void free_task(gpointer data)
+{
+       struct connman_task *task = data;
+
+       DBG("task %p", task);
+
+       g_free(task->path);
+       g_free(task);
+}
+
+struct connman_task *connman_task_create(void)
+{
+       struct connman_task *task;
+       gint counter;
+
+       DBG("");
+
+       task = g_try_new0(struct connman_task, 1);
+       if (task == NULL)
+               return NULL;
+
+       counter = g_atomic_int_exchange_and_add(&task_counter, 1);
+
+       task->path = g_strdup_printf("/task/%d", counter);
+       task->pid = -1;
+
+       DBG("task %p", task);
+
+       g_hash_table_insert(task_hash, task->path, task);
+
+       return task;
+}
+
+void connman_task_destroy(struct connman_task *task)
+{
+       DBG("task %p", task);
+
+       g_hash_table_remove(task_hash, task->path);
+}
+
+static DBusHandlerResult task_filter(DBusConnection *connection,
+                                       DBusMessage *message, void *user_data)
+{
+       struct connman_task *task;
+       const char *path;
+
+       if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
+               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+       if (dbus_message_has_interface(message,
+                                       CONNMAN_TASK_INTERFACE) == FALSE)
+               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+       path = dbus_message_get_path(message);
+       if (path == NULL)
+               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+       task = g_hash_table_lookup(task_hash, path);
+       if (task == NULL)
+               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+       return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static const char *task_rule = "type=method_call"
+                                       ",interface=" CONNMAN_TASK_INTERFACE;
+
+static DBusConnection *connection;
+
+int __connman_task_init(void)
+{
+       DBG("");
+
+       connection = connman_dbus_get_connection();
+
+       dbus_connection_add_filter(connection, task_filter, NULL, NULL);
+
+       g_atomic_int_set(&task_counter, 0);
+
+       task_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                                       NULL, free_task);
+
+       dbus_bus_add_match(connection, task_rule, NULL);
+       dbus_connection_flush(connection);
+
+       return 0;
+}
+
+void __connman_task_cleanup(void)
+{
+       DBG("");
+
+       dbus_bus_remove_match(connection, task_rule, NULL);
+       dbus_connection_flush(connection);
+
+       g_hash_table_destroy(task_hash);
+       task_hash = NULL;
+
+       dbus_connection_remove_filter(connection, task_filter, NULL);
+
+       dbus_connection_unref(connection);
+}