summaryrefslogtreecommitdiff
path: root/src/rtnl.c
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 /src/rtnl.c
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.
Diffstat (limited to 'src/rtnl.c')
-rw-r--r--src/rtnl.c74
1 files changed, 74 insertions, 0 deletions
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;