[PATCH 5/6] base-bearer: setup periodic stats loading
Dan Williams
dcbw at redhat.com
Mon Nov 30 08:33:39 PST 2015
On Fri, 2015-11-27 at 14:51 +0100, Aleksander Morgado wrote:
> If the bearer implementation supports it, load stats periodically. By
> default
> every 30s for now.
> ---
> src/mm-base-bearer.c | 123
> +++++++++++++++++++++++++++++++++++++++++++++++++--
> src/mm-base-bearer.h | 16 +++++--
> 2 files changed, 133 insertions(+), 6 deletions(-)
>
> diff --git a/src/mm-base-bearer.c b/src/mm-base-bearer.c
> index 1b1c7b3..117f144 100644
> --- a/src/mm-base-bearer.c
> +++ b/src/mm-base-bearer.c
> @@ -13,7 +13,8 @@
> * Copyright (C) 2008 - 2009 Novell, Inc.
> * Copyright (C) 2009 - 2011 Red Hat, Inc.
> * Copyright (C) 2011 Google, Inc.
> - * Copyright (C) 2011 - 2014 Aleksander Morgado <
> aleksander at aleksander.es>
> + * Copyright (C) 2015 Azimut Electronics
> + * Copyright (C) 2011 - 2015 Aleksander Morgado <
> aleksander at aleksander.es>
> */
>
> #include <config.h>
> @@ -36,13 +37,16 @@
> #include "mm-base-modem.h"
> #include "mm-log.h"
> #include "mm-modem-helpers.h"
> +#include "mm-bearer-stats.h"
>
> /* We require up to 20s to get a proper IP when using PPP */
> #define BEARER_IP_TIMEOUT_DEFAULT 20
>
> #define BEARER_DEFERRED_UNREGISTRATION_TIMEOUT 15
>
> -G_DEFINE_TYPE (MMBaseBearer, mm_base_bearer,
> MM_GDBUS_TYPE_BEARER_SKELETON);
> +#define BEARER_STATS_UPDATE_TIMEOUT 30
> +
> +G_DEFINE_TYPE (MMBaseBearer, mm_base_bearer,
> MM_GDBUS_TYPE_BEARER_SKELETON)
>
> typedef enum {
> CONNECTION_FORBIDDEN_REASON_NONE,
> @@ -97,6 +101,13 @@ struct _MMBaseBearerPrivate {
> /* Handler IDs for the registration state change signals */
> guint id_cdma1x_registration_change;
> guint id_evdo_registration_change;
> +
> + /* The stats object to expose */
> + MMBearerStats *stats;
> + /* Handler id for the stats update timeout */
> + guint stats_update_id;
> + /* Timer to measure the duration of the connection */
> + GTimer *duration_timer;
> };
>
> /*******************************************************************
> **********/
> @@ -125,6 +136,102 @@ mm_base_bearer_export (MMBaseBearer *self)
> /*******************************************************************
> **********/
>
> static void
> +bearer_update_interface_stats (MMBaseBearer *self)
> +{
> + mm_gdbus_bearer_set_stats (
> + MM_GDBUS_BEARER (self),
> + mm_bearer_stats_get_dictionary (self->priv->stats));
> +}
> +
> +static void
> +bearer_reset_interface_stats (MMBaseBearer *self)
> +{
> + g_clear_object (&self->priv->stats);
> + mm_gdbus_bearer_set_stats (MM_GDBUS_BEARER (self), NULL);
> +}
> +
> +static void
> +bearer_stats_stop (MMBaseBearer *self)
> +{
> + if (self->priv->duration_timer) {
> + if (self->priv->stats)
> + mm_bearer_stats_set_duration (self->priv->stats,
> (guint64) g_timer_elapsed (self->priv->duration_timer, NULL));
> + g_timer_destroy (self->priv->duration_timer);
> + self->priv->duration_timer = NULL;
> + }
> +
> + if (self->priv->stats_update_id) {
> + g_source_remove (self->priv->stats_update_id);
> + self->priv->stats_update_id = 0;
> + }
> +}
> +
> +static void
> +reload_stats_ready (MMBaseBearer *self,
> + GAsyncResult *res)
> +{
> + GError *error = NULL;
> + guint64 bytes_rx = 0;
> + guint64 bytes_tx = 0;
> +
> + if (!MM_BASE_BEARER_GET_CLASS (self)->reload_stats_finish (self,
> &bytes_rx, &bytes_tx, res, &error)) {
> + g_warning ("Reloading stats failed: %s", error->message);
> + g_error_free (error);
> + return;
> + }
> +
> + /* We only update stats if they were retrieved properly */
> + mm_bearer_stats_set_duration (self->priv->stats, (guint32)
> g_timer_elapsed (self->priv->duration_timer, NULL));
> + mm_bearer_stats_set_bytes_tx (self->priv->stats, bytes_rx);
> + mm_bearer_stats_set_bytes_rx (self->priv->stats, bytes_tx);
> + bearer_update_interface_stats (self);
> +}
> +
> +static gboolean
> +stats_update_cb (MMBaseBearer *self)
> +{
> + /* If the implementation knows how to update stat values, run it
> */
> + if (MM_BASE_BEARER_GET_CLASS (self)->reload_stats &&
> + MM_BASE_BEARER_GET_CLASS (self)->reload_stats_finish) {
> + MM_BASE_BEARER_GET_CLASS (self)->reload_stats (
> + self,
> + (GAsyncReadyCallback)reload_stats_ready,
> + NULL);
> + return TRUE;
> + }
> +
> + /* Otherwise, just update duration and we're done */
> + mm_bearer_stats_set_duration (self->priv->stats, (guint32)
> g_timer_elapsed (self->priv->duration_timer, NULL));
> + mm_bearer_stats_set_bytes_tx (self->priv->stats, 0);
> + mm_bearer_stats_set_bytes_rx (self->priv->stats, 0);
> + bearer_update_interface_stats (self);
> + return TRUE;
>
I'm a fan of G_SOURCE_CONTINUE/G_SOURCE_REMOVE these days, but that's
personal preference.
Dan
> +}
> +
> +static void
> +bearer_stats_start (MMBaseBearer *self)
> +{
> + /* Allocate new stats object. If there was one already created
> from a
> + * previous run, deallocate it */
> + g_assert (!self->priv->stats);
> + self->priv->stats = mm_bearer_stats_new ();
> +
> + /* Start duration timer */
> + g_assert (!self->priv->duration_timer);
> + self->priv->duration_timer = g_timer_new ();
> +
> + /* Schedule */
> + g_assert (!self->priv->stats_update_id);
> + self->priv->stats_update_id = g_timeout_add_seconds
> (BEARER_STATS_UPDATE_TIMEOUT,
> +
> (GSourceFunc) stats_update_cb,
> + self);
> + /* Load initial values */
> + stats_update_cb (self);
> +}
> +
> +/*******************************************************************
> **********/
> +
> +static void
> bearer_reset_interface_status (MMBaseBearer *self)
> {
> mm_gdbus_bearer_set_connected (MM_GDBUS_BEARER (self), FALSE);
> @@ -151,8 +258,11 @@ bearer_update_status (MMBaseBearer *self,
>
> /* Ensure that we don't expose any connection related data in
> the
> * interface when going into disconnected state. */
> - if (self->priv->status == MM_BEARER_STATUS_DISCONNECTED)
> + if (self->priv->status == MM_BEARER_STATUS_DISCONNECTED) {
> bearer_reset_interface_status (self);
> + /* Stop statistics */
> + bearer_stats_stop (self);
> + }
> }
>
> static void
> @@ -171,6 +281,9 @@ bearer_update_status_connected (MMBaseBearer
> *self,
> MM_GDBUS_BEARER (self),
> mm_bearer_ip_config_get_dictionary (ipv6_config));
>
> + /* Start statistics */
> + bearer_stats_start (self);
> +
> /* Update the property value */
> self->priv->status = MM_BEARER_STATUS_CONNECTED;
> g_object_notify_by_pspec (G_OBJECT (self),
> properties[PROP_STATUS]);
> @@ -590,6 +703,7 @@ mm_base_bearer_connect (MMBaseBearer *self,
> mm_dbg ("Connecting bearer '%s'", self->priv->path);
> self->priv->connect_cancellable = g_cancellable_new ();
> bearer_update_status (self, MM_BEARER_STATUS_CONNECTING);
> + bearer_reset_interface_stats (self);
> MM_BASE_BEARER_GET_CLASS (self)->connect (
> self,
> self->priv->connect_cancellable,
> @@ -1150,6 +1264,9 @@ dispose (GObject *object)
> {
> MMBaseBearer *self = MM_BASE_BEARER (object);
>
> + bearer_stats_stop (self);
> + g_clear_object (&self->priv->stats);
> +
> if (self->priv->connection) {
> base_bearer_dbus_unexport (self);
> g_clear_object (&self->priv->connection);
> diff --git a/src/mm-base-bearer.h b/src/mm-base-bearer.h
> index 2c196f6..58954d4 100644
> --- a/src/mm-base-bearer.h
> +++ b/src/mm-base-bearer.h
> @@ -10,10 +10,10 @@
> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> * GNU General Public License for more details:
> *
> - * Author: Aleksander Morgado <aleksander at lanedo.com>
> - *
> +
> * Copyright (C) 2011 Google, Inc.
> - * Copyright (C) 2011 - 2013 Aleksander Morgado <aleksander at gnu.org>
> + * Copyright (C) 2015 Azimut Electronics
> + * Copyright (C) 2011 - 2015 Aleksander Morgado <
> aleksander at aleksander.es>
> */
>
> #ifndef MM_BASE_BEARER_H
> @@ -101,6 +101,16 @@ struct _MMBaseBearerClass {
> GAsyncResult *res,
> GError **error);
>
> + /* Reload statistics */
> + void (* reload_stats) (MMBaseBearer *bearer,
> + GAsyncReadyCallback callback,
> + gpointer user_data);
> + gboolean (* reload_stats_finish) (MMBaseBearer *bearer,
> + guint64 *bytes_rx,
> + guint64 *bytes_tx,
> + GAsyncResult *res,
> + GError **error);
> +
> /* Report connection status of this bearer */
> void (* report_connection_status) (MMBaseBearer *bearer,
> MMBearerConnectionStatus
> status);
More information about the ModemManager-devel
mailing list