summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Wagner <daniel.wagner@bmw-carit.de>2010-06-30 13:59:50 +0200
committerSamuel Ortiz <sameo@linux.intel.com>2010-06-30 19:24:58 +0200
commite4fb1ca873f840acd1e0a72a6f266843f65854ae (patch)
treed388378c8116c76be0f0795e549d10a82bec749b
parent46d8e827d58417870243a5645c97adffc189303e (diff)
downloadconnman-e4fb1ca873f840acd1e0a72a6f266843f65854ae.tar.gz
connman-e4fb1ca873f840acd1e0a72a6f266843f65854ae.tar.bz2
connman-e4fb1ca873f840acd1e0a72a6f266843f65854ae.zip
Centralize rntl update timers
Instead of creating a new rntl trigger for each Counter object move this part to the rtnl core. Only one update trigger will be registered at RTNL. The minimum interval will used for the timeout callback.
-rw-r--r--src/connman.h2
-rw-r--r--src/counter.c23
-rw-r--r--src/rtnl.c74
-rwxr-xr-xtest/test-counter9
4 files changed, 87 insertions, 21 deletions
diff --git a/src/connman.h b/src/connman.h
index 62113466..8bf5e970 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 d897fb59..bf9da902 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 9238dde0..2e0fca98 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 val_a = GPOINTER_TO_UINT(a);
+ guint val_b = GPOINTER_TO_UINT(b);
+
+ return val_a - val_b;
+}
+
+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 (update_list != NULL)
+ 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 6a42885e..70a30273 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()