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

Reply via email to