From: Daniel Wagner <daniel.wag...@bmw-carit.de> Instead of creating a new rntl trigger for each Counter object move this part to the rtnl core. The minimum interval will used for the timeout callback. ---
v1: sort interval list v0: initial version src/connman.h | 2 + src/counter.c | 23 +++------------- src/rtnl.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++ test/test-counter | 9 +++++- 4 files changed, 87 insertions(+), 21 deletions(-) diff --git a/src/connman.h b/src/connman.h index 6211346..8bf5e97 100644 --- a/src/connman.h +++ b/src/connman.h @@ -490,6 +490,8 @@ int __connman_rtnl_init(void); void __connman_rtnl_start(void); void __connman_rtnl_cleanup(void); +unsigned int __connman_rtnl_update_interval_add(unsigned int interval); +unsigned int __connman_rtnl_update_interval_remove(unsigned int interval); int __connman_rtnl_request_update(void); int __connman_rtnl_send(const void *buf, size_t len); diff --git a/src/counter.c b/src/counter.c index d897fb5..bf9da90 100644 --- a/src/counter.c +++ b/src/counter.c @@ -42,7 +42,7 @@ struct connman_stats { struct connman_counter { char *owner; char *path; - guint timeout; + unsigned int interval; guint watch; }; @@ -63,8 +63,7 @@ static void remove_counter(gpointer user_data) if (counter->watch > 0) g_dbus_remove_watch(connection, counter->watch); - if (counter->timeout > 0) - g_source_remove(counter->timeout); + __connman_rtnl_update_interval_remove(counter->interval); g_free(counter->owner); g_free(counter->path); @@ -81,17 +80,6 @@ static void owner_disconnect(DBusConnection *connection, void *user_data) g_hash_table_remove(counter_table, counter->path); } -static gboolean counter_timeout(gpointer user_data) -{ - struct connman_counter *counter = user_data; - - DBG("owner %s path %s", counter->owner, counter->path); - - __connman_rtnl_request_update(); - - return TRUE; -} - int __connman_counter_register(const char *owner, const char *path, unsigned int interval) { @@ -113,15 +101,12 @@ int __connman_counter_register(const char *owner, const char *path, g_hash_table_replace(counter_table, counter->path, counter); g_hash_table_replace(owner_mapping, counter->owner, counter); - if (interval > 0) - counter->timeout = g_timeout_add_seconds(interval, - counter_timeout, counter); + counter->interval = interval; + __connman_rtnl_update_interval_add(counter->interval); counter->watch = g_dbus_add_disconnect_watch(connection, owner, owner_disconnect, counter, NULL); - __connman_rtnl_request_update(); - return 0; } diff --git a/src/rtnl.c b/src/rtnl.c index 9238dde..4435c24 100644 --- a/src/rtnl.c +++ b/src/rtnl.c @@ -52,6 +52,10 @@ struct watch_data { static GSList *watch_list = NULL; static unsigned int watch_id = 0; +static GSList *update_list = NULL; +static guint update_interval = G_MAXUINT; +static guint update_timeout = 0; + /** * connman_rtnl_add_operstate_watch: * @index: network device index @@ -1073,6 +1077,73 @@ static int send_getroute(void) return queue_request(req); } +static gboolean update_timeout_cb(gpointer user_data) +{ + __connman_rtnl_request_update(); + + return TRUE; +} + +static void update_interval_callback(guint min) +{ + if (update_timeout > 0) + g_source_remove(update_timeout); + + if (min < G_MAXUINT) { + update_interval = min; + update_timeout = g_timeout_add_seconds(update_interval, + update_timeout_cb, NULL); + } else { + update_timeout = 0; + update_interval = G_MAXUINT; + } +} + +static gint compare_interval(gconstpointer a, gconstpointer b) +{ + guint i = GPOINTER_TO_UINT(a); + guint j = GPOINTER_TO_UINT(b); + + return i - j; +} + +unsigned int __connman_rtnl_update_interval_add(unsigned int interval) +{ + guint min; + + if (interval == 0) + return 0; + + update_list = g_slist_insert_sorted(update_list, + GUINT_TO_POINTER(interval), compare_interval); + + min = GPOINTER_TO_UINT(g_slist_nth_data(update_list, 0)); + if (min < update_interval) { + update_interval_callback(min); + __connman_rtnl_request_update(); + } + + return update_interval; +} + +unsigned int __connman_rtnl_update_interval_remove(unsigned int interval) +{ + guint min = G_MAXUINT; + + if (interval == 0) + return 0; + + update_list = g_slist_remove(update_list, GINT_TO_POINTER(interval)); + + if (g_slist_length(update_list) != 0) + min = GPOINTER_TO_UINT(g_slist_nth_data(update_list, 0)); + + if (min > update_interval) + update_interval_callback(min); + + return min; +} + int __connman_rtnl_request_update(void) { return send_getlink(); @@ -1134,6 +1205,9 @@ void __connman_rtnl_cleanup(void) g_slist_free(watch_list); watch_list = NULL; + g_slist_free(update_list); + update_list = NULL; + for (list = request_list; list; list = list->next) { struct rtnl_request *req = list->data; diff --git a/test/test-counter b/test/test-counter index 6a42885..70a3027 100755 --- a/test/test-counter +++ b/test/test-counter @@ -1,5 +1,6 @@ #!/usr/bin/python +import sys import gobject import dbus @@ -30,10 +31,14 @@ if __name__ == '__main__': manager = dbus.Interface(bus.get_object('org.moblin.connman', "/"), 'org.moblin.connman.Manager') - path = "/test/counter" + interval = 2 + if len(sys.argv) > 1: + interval = sys.argv[1] + + path = "/test/counter%s" % interval object = Counter(bus, path) - manager.RegisterCounter(path, dbus.UInt32(2)) + manager.RegisterCounter(path, dbus.UInt32(interval)) mainloop = gobject.MainLoop() mainloop.run() -- 1.6.6.1 _______________________________________________ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman