summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2014-03-12 15:51:11 +0100
committerThomas Haller <thaller@redhat.com>2014-06-20 08:15:37 +0200
commitaaf0ef42dd26c0e67b27770c6c8e08c0e104998d (patch)
treec0cb9982511d4d883a3b825ffee31dda0c0d2f39
parent9a06f1a2eb62a27794d7ffba9e0cde3d0f68bd41 (diff)
downloadNetworkManager-aaf0ef42dd26c0e67b27770c6c8e08c0e104998d.tar.gz
nm-online: refactor calculation of wait timeout for better accuracy
Also, in verbose mode, synchronize the printing of the progress bar and the counting seconds so that the output appears smooth. This schedules the timeouts so that there are roughly (PROGRESS_STEPS + n_secs) wakeups. https://bugzilla.gnome.org/show_bug.cgi?id=728163 Signed-off-by: Thomas Haller <thaller@redhat.com>
-rw-r--r--test/nm-online.c75
1 files changed, 53 insertions, 22 deletions
diff --git a/test/nm-online.c b/test/nm-online.c
index 8119287464..3fcb9601b7 100644
--- a/test/nm-online.c
+++ b/test/nm-online.c
@@ -47,8 +47,9 @@
typedef struct
{
- int value;
- double norm;
+ gint64 start_timestamp_ms;
+ gint64 end_timestamp_ms;
+ gint64 progress_step_duration;
gboolean quiet;
} Timeout;
@@ -79,32 +80,60 @@ client_properties_changed (GObject *object,
static gboolean
handle_timeout (gpointer data)
{
- int i = PROGRESS_STEPS;
- Timeout *timeout = data;
+ const Timeout *timeout = data;
+ const gint64 now = g_get_monotonic_time () / (G_USEC_PER_SEC / 1000);
+ gint64 remaining_ms = timeout->end_timestamp_ms - now;
+ const gint64 elapsed_ms = now - timeout->start_timestamp_ms;
+ int progress_next_step_i = 0;
if (!timeout->quiet) {
+ int i;
+
+ /* calculate the next step (not the current): floor()+1 */
+ progress_next_step_i = (elapsed_ms / timeout->progress_step_duration) + 1;
+ progress_next_step_i = MIN (progress_next_step_i, PROGRESS_STEPS);
+
g_print (_("\rConnecting"));
- for (; i > 0; i--)
- putchar ((timeout->value >= (i * timeout->norm)) ? ' ' : '.');
- if (timeout->value)
- g_print (" %4is", timeout->value);
+ for (i = 0; i < PROGRESS_STEPS; i++)
+ putchar (i < progress_next_step_i ? '.' : ' ');
+ g_print (" %4lds", (long) (MAX (0, remaining_ms) / 1000));
fflush (stdout);
}
- timeout->value--;
- if (timeout->value < 0) {
+ if (remaining_ms <= 3) {
if (!timeout->quiet)
g_print ("\n");
exit (1);
}
- return TRUE;
+ if (!timeout->quiet) {
+ gint64 rem;
+
+ /* synchronize the timeout with the ticking of the seconds. */
+ rem = remaining_ms % 1000;
+ if (rem <= 3)
+ rem = rem + G_USEC_PER_SEC;
+ rem = rem + 10; /* add small offset to awake a bit after the second ticks */
+ if (remaining_ms > rem)
+ remaining_ms = rem;
+
+ /* synchronize the timeout with the steps of the progress bar. */
+ rem = (progress_next_step_i * timeout->progress_step_duration) - elapsed_ms;
+ if (rem <= 3)
+ rem = rem + timeout->progress_step_duration;
+ rem = rem + 10; /* add small offset to awake a bit after the time out */
+ if (remaining_ms > rem)
+ remaining_ms = rem;
+ }
+
+ g_timeout_add (remaining_ms, handle_timeout, (void *) timeout);
+ return G_SOURCE_REMOVE;
}
int
main (int argc, char *argv[])
{
- gint t_secs = -1;
+ int t_secs = 30;
gboolean exit_no_nm = FALSE;
gboolean wait_startup = FALSE;
Timeout timeout;
@@ -113,6 +142,7 @@ main (int argc, char *argv[])
NMClient *client;
NMState state = NM_STATE_UNKNOWN;
GMainLoop *loop;
+ gint64 remaining_ms;
GOptionEntry options[] = {
{"timeout", 't', 0, G_OPTION_ARG_INT, &t_secs, N_("Time to wait for a connection, in seconds (without the option, default value is 30)"), "<timeout>"},
@@ -122,6 +152,7 @@ main (int argc, char *argv[])
{NULL}
};
+ timeout.start_timestamp_ms = g_get_monotonic_time () / (G_USEC_PER_SEC / 1000);
timeout.quiet = FALSE;
/* Set locale to be able to use environment variables */
@@ -148,16 +179,13 @@ main (int argc, char *argv[])
_("Invalid option. Please use --help to see a list of valid options."));
return 2;
}
-
- if (t_secs > -1)
- timeout.value = t_secs;
- else
- timeout.value = 30;
- if (timeout.value < 0 || timeout.value > 3600) {
+
+ if (t_secs < 0 || t_secs > 3600) {
g_printerr ("%s: %s\n", argv[0],
_("Invalid option. Please use --help to see a list of valid options."));
return 2;
}
+ remaining_ms = t_secs * 1000;
#if !GLIB_CHECK_VERSION (2, 35, 0)
g_type_init ();
@@ -196,17 +224,20 @@ main (int argc, char *argv[])
return 1;
}
- if (!timeout.value) {
+ if (remaining_ms == 0) {
g_object_unref (client);
return 1;
}
- timeout.norm = (double) timeout.value / (double) PROGRESS_STEPS;
- g_timeout_add_seconds (1, handle_timeout, &timeout);
-
g_signal_connect (client, "notify",
G_CALLBACK (client_properties_changed), loop);
+ timeout.end_timestamp_ms = timeout.start_timestamp_ms + remaining_ms;
+ timeout.progress_step_duration = (timeout.end_timestamp_ms - timeout.start_timestamp_ms + PROGRESS_STEPS/2) / PROGRESS_STEPS;
+
+ g_timeout_add (timeout.quiet ? remaining_ms : 0,
+ handle_timeout, &timeout);
+
g_main_loop_run (loop);
g_main_loop_unref (loop);