diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2009-04-07 16:54:19 -0700 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2009-04-07 21:02:48 -0700 |
commit | c6dc4196705b7b93e11b6687b10cc49a7f038c34 (patch) | |
tree | 448353cc31e89aeebb96c570517cc175c406e4a2 /src/service.c | |
parent | 5a5a93105bd1e2e70044b4d466a7a37ec696c94d (diff) | |
download | connman-c6dc4196705b7b93e11b6687b10cc49a7f038c34.tar.gz connman-c6dc4196705b7b93e11b6687b10cc49a7f038c34.tar.bz2 connman-c6dc4196705b7b93e11b6687b10cc49a7f038c34.zip |
Add service initialization and lifetime tracking support
Diffstat (limited to 'src/service.c')
-rw-r--r-- | src/service.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/service.c b/src/service.c index f272fe37..9c95fc6e 100644 --- a/src/service.c +++ b/src/service.c @@ -25,7 +25,14 @@ #include "connman.h" +static DBusConnection *connection = NULL; + +static GSequence *service_list = NULL; +static GHashTable *service_hash = NULL; + struct connman_service { + gint refcount; + char *identifier; char *path; enum connman_service_type type; enum connman_service_mode mode; @@ -35,3 +42,104 @@ struct connman_service { connman_bool_t favorite; char *name; }; + +static void service_free(gpointer data) +{ + struct connman_service *service = data; + + DBG("service %p", service); + + g_hash_table_remove(service_hash, service->identifier); + + g_free(service->name); + g_free(service->path); + g_free(service->identifier); + g_free(service); +} + +static gint service_compare(gconstpointer a, gconstpointer b, + gpointer user_data) +{ + struct connman_service *service_a = (void *) a; + struct connman_service *service_b = (void *) b; + + if (service_a->favorite == TRUE && service_b->favorite == FALSE) + return -1; + + if (service_a->favorite == FALSE && service_b->favorite == TRUE) + return 1; + + return (gint) service_b->strength - (gint) service_a->strength; +} + +struct connman_service *connman_service_get(const char *identifier) +{ + struct connman_service *service; + GSequenceIter *iter; + + iter = g_hash_table_lookup(service_hash, identifier); + if (iter != NULL) { + service = g_sequence_get(iter); + if (service != NULL) + g_atomic_int_inc(&service->refcount); + return service; + } + + service = g_try_new0(struct connman_service, 1); + if (service == NULL) + return NULL; + + DBG("service %p", service); + + service->refcount = 1; + service->identifier = g_strdup(identifier); + + iter = g_sequence_insert_sorted(service_list, service, + service_compare, NULL); + + g_hash_table_insert(service_hash, service->identifier, iter); + + return service; +} + +void connman_service_put(struct connman_service *service) +{ + DBG("service %p", service); + + if (g_atomic_int_dec_and_test(&service->refcount) == TRUE) { + GSequenceIter *iter; + + iter = g_hash_table_lookup(service_hash, service->identifier); + if (iter != NULL) + g_sequence_remove(iter); + else + service_free(service); + } +} + +int __connman_service_init(void) +{ + DBG(""); + + connection = connman_dbus_get_connection(); + + service_hash = g_hash_table_new_full(g_str_hash, g_str_equal, + NULL, NULL); + + service_list = g_sequence_new(service_free); + + return 0; +} + +void __connman_service_cleanup(void) +{ + DBG(""); + + g_sequence_free(service_list); + service_list = NULL; + + g_hash_table_destroy(service_hash); + service_hash = NULL; + + dbus_connection_unref(connection); +} |