struct connman_counter {
char *owner;
char *path;
- guint timeout;
+ unsigned int interval;
guint watch;
};
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);
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)
{
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;
}
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
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();
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;
#!/usr/bin/python
+import sys
import gobject
import dbus
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()