X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Ftask.c;h=97de7e351c9c1948321e451095395fa782eb45ef;hb=c329f0f22773df936ef31c539d8fd32c3a973659;hp=37bbe71fbe622a1b29ac739d997c615f93c338ec;hpb=8b2d9ae04a651d145e42f05fd61af6c1aad03b69;p=framework%2Fconnectivity%2Fconnman.git diff --git a/src/task.c b/src/task.c index 37bbe71..97de7e3 100644 --- a/src/task.c +++ b/src/task.c @@ -2,7 +2,7 @@ * * Connection Manager * - * Copyright (C) 2007-2010 Intel Corporation. All rights reserved. + * Copyright (C) 2007-2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -23,9 +23,11 @@ #include #endif +#include #include #include #include +#include #include @@ -49,7 +51,7 @@ struct connman_task { static GHashTable *task_hash = NULL; -static volatile gint task_counter; +static volatile int task_counter; static DBusConnection *connection; @@ -103,7 +105,7 @@ struct connman_task *connman_task_create(const char *program) if (task == NULL) return NULL; - counter = g_atomic_int_exchange_and_add(&task_counter, 1); + counter = __sync_fetch_and_add(&task_counter, 1); task->path = g_strdup_printf("/task/%d", counter); task->pid = -1; @@ -238,7 +240,7 @@ int connman_task_set_notify(struct connman_task *task, const char *member, notify->func = function; notify->data = user_data; - g_hash_table_insert(task->notify, g_strdup(member), notify); + g_hash_table_replace(task->notify, g_strdup(member), notify); return 0; } @@ -267,9 +269,14 @@ static void task_died(GPid pid, gint status, gpointer user_data) static void task_setup(gpointer user_data) { + sigset_t mask; struct connman_task *task = user_data; DBG("task %p", task); + + sigemptyset(&mask); + if (sigprocmask(SIG_SETMASK, &mask, NULL) < 0) + connman_error("Failed to clean signal mask"); } /** @@ -343,6 +350,44 @@ int connman_task_run(struct connman_task *task, return 0; } +static gboolean force_kill_timeout(gpointer user_data) +{ + pid_t pid = GPOINTER_TO_INT(user_data); + if (pid > 0) { + if (kill(pid, SIGKILL) == 0) + connman_warn("killing pid %d by force", pid); + } + + return FALSE; +} + +static gboolean kill_timeout(gpointer user_data) +{ + pid_t pid = GPOINTER_TO_INT(user_data); + if (pid > 0) { + if (kill(pid, SIGINT) == 0) + g_timeout_add_seconds(1, force_kill_timeout, + GINT_TO_POINTER(pid)); + } + + return FALSE; +} + +static gboolean check_kill(gpointer user_data) +{ + pid_t pid = GPOINTER_TO_INT(user_data); + if (pid > 0) { + if (kill(pid, 0) == 0) { + connman_info("pid %d was not killed, " + "retrying after 2 sec", pid); + g_timeout_add_seconds(2, kill_timeout, + GINT_TO_POINTER(pid)); + } + } + + return FALSE; +} + /** * connman_task_stop: * @task: task structure @@ -353,9 +398,13 @@ int connman_task_stop(struct connman_task *task) { DBG("task %p", task); - if (task->pid > 0) + if (task->pid > 0) { kill(task->pid, SIGTERM); + g_timeout_add_seconds(0, check_kill, + GINT_TO_POINTER(task->pid)); + } + return 0; } @@ -365,6 +414,7 @@ static DBusHandlerResult task_filter(DBusConnection *connection, struct connman_task *task; struct notify_data *notify; const char *path, *member; + DBusMessage *reply = NULL; if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_METHOD_CALL) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; @@ -381,29 +431,32 @@ static DBusHandlerResult task_filter(DBusConnection *connection, if (task == NULL) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - if (dbus_message_get_no_reply(message) == FALSE) { - DBusMessage *reply; + member = dbus_message_get_member(message); + if (member == NULL) + goto send_reply; + + notify = g_hash_table_lookup(task->notify, member); + if (notify == NULL) + goto send_reply; + + if (notify->func) + reply = notify->func(task, message, notify->data); + +send_reply: + if (dbus_message_get_no_reply(message) == FALSE && + reply == NULL) { reply = dbus_message_new_method_return(message); if (reply == NULL) return DBUS_HANDLER_RESULT_NEED_MEMORY; + } + if (reply != NULL) { dbus_connection_send(connection, reply, NULL); dbus_message_unref(reply); } - member = dbus_message_get_member(message); - if (member == NULL) - return DBUS_HANDLER_RESULT_HANDLED; - - notify = g_hash_table_lookup(task->notify, member); - if (notify == NULL) - return DBUS_HANDLER_RESULT_HANDLED; - - if (notify->func) - notify->func(task, message, notify->data); - return DBUS_HANDLER_RESULT_HANDLED; } @@ -418,7 +471,8 @@ int __connman_task_init(void) dbus_connection_add_filter(connection, task_filter, NULL, NULL); - g_atomic_int_set(&task_counter, 0); + task_counter = 0; + __sync_synchronize(); task_hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, free_task);