This allows the progress to be retained between calls to splash plugins.
-I$(srcdir)/libplybootsplash \
-I$(srcdir) \
-DPLYMOUTH_LOG_DIRECTORY=\"$(localstatedir)/log\" \
- -DPLYMOUTH_TIME_DIRECTORY=\"$(localstatedir)/lib/plymouth/\" \
-DPLYMOUTH_SPOOL_DIRECTORY=\"$(localstatedir)/spool/plymouth\" \
-DPLYMOUTH_LOGO_FILE=\"$(logofile)\"
SUBDIRS = tests
INCLUDES = -I$(top_srcdir) \
- -I$(srcdir)
+ -I$(srcdir) \
+ -DPLYMOUTH_TIME_DIRECTORY=\"$(localstatedir)/lib/plymouth/\"
if WITH_SYSTEM_ROOT_INSTALL
librarydir = $(libdir:/usr%=%)
ply-array.h \
ply-list.h \
ply-logger.h \
+ ply-progress.h \
ply-terminal.h \
ply-terminal-session.h \
ply-trigger.h \
ply-array.c \
ply-list.c \
ply-logger.c \
+ ply-progress.c \
ply-terminal.c \
ply-terminal-session.c \
ply-trigger.c \
--- /dev/null
+/* ply-progress.c - calculats boot progress
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Written By: Ray Strode <rstrode@redhat.com>
+ * Soeren Sandmann <sandmann@redhat.com>
+ * Charlie Brej <cbrej@cs.man.ac.uk>
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+
+#include "ply-logger.h"
+#include "ply-progress.h"
+#include "ply-utils.h"
+
+#ifndef UPDATES_PER_SECOND
+#define UPDATES_PER_SECOND 30
+#endif
+
+#ifndef DEFAULT_BOOT_DURATION
+#define DEFAULT_BOOT_DURATION 60.0
+#endif
+
+#define BOOT_DURATION_FILE PLYMOUTH_TIME_DIRECTORY "/boot-duration"
+
+
+struct _ply_progress
+{
+ double boot_duration;
+ double start_time;
+ double wait_time;
+};
+
+ply_progress_t*
+ply_progress_new (void)
+{
+ ply_progress_t *progress = calloc (1, sizeof (ply_progress_t));
+
+ progress->boot_duration = DEFAULT_BOOT_DURATION;
+ progress->start_time = ply_get_timestamp ();
+ progress->wait_time=0;
+
+ return progress;
+}
+
+void
+ply_progress_free (ply_progress_t* progress)
+{
+ free(progress);
+ return;
+}
+
+
+void
+ply_progress_load_cache (ply_progress_t* progress)
+{
+ FILE *fp;
+ int items_matched;
+
+ fp = fopen (BOOT_DURATION_FILE,"r");
+
+ if (fp == NULL)
+ return;
+
+ items_matched = fscanf (fp, "%lf", &progress->boot_duration);
+
+ fclose (fp);
+
+ if (items_matched != 1)
+ progress->boot_duration = DEFAULT_BOOT_DURATION;
+}
+
+void
+ply_progress_save_cache (ply_progress_t* progress)
+{
+ FILE *fp;
+ fp = fopen (BOOT_DURATION_FILE,"w");
+ if (fp != NULL)
+ {
+ fprintf (fp, "%.1lf\n", (ply_get_timestamp () - progress->start_time));
+ fclose (fp);
+ }
+}
+
+
+double
+ply_progress_get_percentage (ply_progress_t* progress)
+{
+ return CLAMP((ply_get_timestamp() - progress->start_time)/progress->boot_duration, 0, 1);
+
+}
+
+
+double
+ply_progress_get_time (ply_progress_t* progress)
+{
+ return ply_get_timestamp() - progress->start_time;
+}
+
+void
+ply_progress_pause (ply_progress_t* progress)
+{
+ progress->wait_time = ply_get_timestamp ();
+ return;
+}
+
+
+void
+ply_progress_unpause (ply_progress_t* progress)
+{
+ progress->start_time += ply_get_timestamp() - progress->wait_time;
+ return;
+}
+
+void
+ply_progress_session_output (ply_progress_t* progress,
+ const char *output,
+ size_t size)
+{
+ return;
+}
+
+
+
+#ifdef PLY_PROGRESS_ENABLE_TEST
+
+#include <stdio.h>
+
+int
+main (int argc,
+ char **argv)
+{
+ double percent;
+ double time;
+ int i;
+ ply_progress_t* progress = ply_progress_new ();
+
+ percent = ply_progress_get_percentage (progress);
+ time = ply_progress_get_time (progress);
+ printf("Time:%f \t Percentage: %f%%\n", time, percent);
+ srand ((int) ply_get_timestamp ());
+
+ for (i=0; i<10; i++)
+ {
+ usleep ((rand () % 500000));
+ percent = ply_progress_get_percentage (progress);
+ time = ply_progress_get_time (progress);
+ printf("Time:%f \t Percentage: %f%%\n", time, percent);
+ }
+ printf("Load cache\n");
+ ply_progress_load_cache (progress);
+
+ for (i=0; i<10; i++)
+ {
+ usleep ((rand () % 500000));
+ percent = ply_progress_get_percentage (progress);
+ time = ply_progress_get_time (progress);
+ printf("Time:%f \t Percentage: %f%%\n", time, percent);
+ }
+
+ printf("Save and reload cache\n");
+ ply_progress_save_cache (progress);
+
+ ply_progress_load_cache (progress);
+
+ percent = ply_progress_get_percentage (progress);
+ time = ply_progress_get_time (progress);
+ printf("Time:%f \t Percentage: %f%%\n", time, percent);
+
+ ply_progress_free(progress);
+ return 0;
+}
+
+#endif /* PLY_PROGRESS_ENABLE_TEST */
+/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
--- /dev/null
+/* ply-progress.h - calculats boot progress
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Written By: Ray Strode <rstrode@redhat.com>
+ * Soeren Sandmann <sandmann@redhat.com>
+ * Charlie Brej <cbrej@cs.man.ac.uk>
+ */
+#ifndef PLY_PROGRESS_H
+#define PLY_PROGRESS_H
+
+
+typedef struct _ply_progress ply_progress_t;
+
+ply_progress_t *ply_progress_new (void);
+ply_progress_t* ply_progress_new (void);
+void ply_progress_free (ply_progress_t* progress);
+void ply_progress_load_cache (ply_progress_t* progress);
+double ply_progress_get_percentage (ply_progress_t* progress);
+double ply_progress_get_time (ply_progress_t* progress);
+void ply_progress_save_cache (ply_progress_t* progress);
+
+#endif /* PLY_PROGRESS_H */
+/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
include $(srcdir)/ply-list-test.am
include $(srcdir)/ply-event-loop-test.am
include $(srcdir)/ply-command-parser-test.am
+include $(srcdir)/ply-progress-test.am
endif
noinst_PROGRAMS = $(TESTS)
--- /dev/null
+TESTS += ply-progress-test
+
+ply_progress_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_PROGRESS_ENABLE_TEST \
+ -DPLYMOUTH_TIME_DIRECTORY=\"$(localstatedir)/lib/plymouth/\"
+ply_progress_test_LDADD = $(PLYMOUTH_LIBS)
+
+ply_progress_test_SOURCES = \
+ $(srcdir)/../ply-progress.h \
+ $(srcdir)/../ply-progress.c \
+ $(srcdir)/../ply-logger.h \
+ $(srcdir)/../ply-logger.c \
+ $(srcdir)/../ply-utils.h \
+ $(srcdir)/../ply-utils.c
#include "ply-terminal-session.h"
#include "ply-trigger.h"
#include "ply-utils.h"
+#include "ply-progress.h"
#ifndef PLY_MAX_COMMAND_LINE_SIZE
#define PLY_MAX_COMMAND_LINE_SIZE 512
ply_boot_splash_t *boot_splash;
ply_terminal_session_t *session;
ply_buffer_t *boot_buffer;
+ ply_progress_t *progress;
long ptmx;
char kernel_command_line[PLY_MAX_COMMAND_LINE_SIZE];
size_t size)
{
ply_buffer_append_bytes (state->boot_buffer, output, size);
+ ply_progress_session_output (state->progress,
+ output, size);
if (state->boot_splash != NULL)
ply_boot_splash_update_output (state->boot_splash,
chdir(root_dir);
chroot(".");
chdir("/");
-
+ ply_progress_load_cache (state->progress);
ply_boot_splash_root_mounted (state->boot_splash);
}
ply_trace ("attaching plugin to event loop");
ply_boot_splash_attach_to_event_loop (splash, state->loop);
+ ply_trace ("attaching progress to plugin");
+ ply_boot_splash_attach_progress (splash, state->progress);
+
ply_trace ("adding windows to boot splash");
add_windows_to_boot_splash (state, splash);
return EX_UNAVAILABLE;
}
+ state.progress = ply_progress_new ();
+ ply_progress_load_cache (state.progress);
ply_trace ("entering event loop");
exit_code = ply_event_loop_run (state.loop);
ply_trace ("exited event loop");
+ ply_progress_save_cache (state.progress);
+
ply_boot_splash_free (state.boot_splash);
state.boot_splash = NULL;
ply_terminal_session_free (state.session);
ply_buffer_free (state.boot_buffer);
+ ply_progress_free (state.progress);
ply_trace ("freeing event loop");
ply_event_loop_free (state.loop);
#include "ply-logger.h"
#include "ply-trigger.h"
#include "ply-utils.h"
+#include "ply-progress.h"
#ifndef UPDATES_PER_SECOND
#define UPDATES_PER_SECOND 30
#endif
-#ifndef DEFAULT_BOOT_DURATION
-#define DEFAULT_BOOT_DURATION 60.0
-#endif
-
-#define BOOT_DURATION_FILE PLYMOUTH_TIME_DIRECTORY "/boot-duration"
struct _ply_boot_splash
{
char *module_name;
char *status;
- double boot_duration;
- double start_time;
- double wait_time;
+ ply_progress_t *progress;
uint32_t is_loaded : 1;
uint32_t is_shown : 1;
return true;
}
-static void
-load_boot_duration (ply_boot_splash_t *splash)
-{
- FILE *fp;
- int items_matched;
-
- fp = fopen (BOOT_DURATION_FILE,"r");
-
- if (fp == NULL)
- return;
-
- items_matched = fscanf (fp, "%lf", &splash->boot_duration);
-
- fclose (fp);
-
- if (items_matched != 1)
- splash->boot_duration = DEFAULT_BOOT_DURATION;
-}
-
-static void
-save_boot_duration (ply_boot_splash_t *splash)
-{
- FILE *fp;
-
- fp = fopen (BOOT_DURATION_FILE,"w");
-
- if (fp != NULL)
- {
- fprintf (fp, "%.1lf\n", (ply_get_timestamp () - splash->start_time));
- fclose (fp);
- }
-}
-
void
ply_boot_splash_unload (ply_boot_splash_t *splash)
{
splash->plugin_interface = NULL;
splash->module_handle = NULL;
- save_boot_duration (splash);
-
splash->is_loaded = false;
}
static void
ply_boot_splash_update_progress (ply_boot_splash_t *splash)
{
- double time_in_seconds;
- double default_percentage;
- double percentage;
+ double percentage=0.0;
+ double time=0.0;
assert (splash != NULL);
- time_in_seconds = ply_get_timestamp () - splash->start_time;
-
- default_percentage = time_in_seconds / DEFAULT_BOOT_DURATION;
- percentage = time_in_seconds / splash->boot_duration;
-
- /* We intepolate the percentage between the real percentage (based
- * on what's stored on disk) with the default percentage (based on
- * a 60 second boot time)
- *
- * This is because we initially assume 60 seconds until / is mounted,
- * and we don't want any large jumps
- */
- percentage = percentage * percentage + default_percentage * (1.0 - percentage);
-
- percentage = CLAMP (percentage, 0.0, 1.0);
+ if (splash->progress)
+ {
+ percentage = ply_progress_get_percentage(splash->progress);
+ time = ply_progress_get_time(splash->progress);
+ }
if (splash->plugin_interface->on_boot_progress != NULL)
splash->plugin_interface->on_boot_progress (splash->plugin,
- time_in_seconds,
+ time,
percentage);
ply_event_loop_watch_for_timeout (splash->loop,
ply_boot_splash_update_progress, splash);
}
+void
+ply_boot_splash_attach_progress (ply_boot_splash_t *splash,
+ ply_progress_t *progress)
+{
+ assert (splash != NULL);
+ assert (progress != NULL);
+ assert (splash->progress == NULL);
+ splash->progress = progress;
+}
+
+
bool
ply_boot_splash_show (ply_boot_splash_t *splash)
{
if (splash->is_shown)
return true;
- splash->start_time = ply_get_timestamp ();
- splash->boot_duration = DEFAULT_BOOT_DURATION;
-
assert (splash->plugin_interface != NULL);
assert (splash->plugin != NULL);
assert (splash->plugin_interface->show_splash_screen != NULL);
if (splash->plugin_interface->on_root_mounted != NULL)
splash->plugin_interface->on_root_mounted (splash->plugin);
-
- if (splash->plugin_interface->on_boot_progress != NULL)
- load_boot_duration (splash);
}
static void
on_password_answered (ply_boot_splash_t *splash)
{
- splash->start_time += (ply_get_timestamp () - splash->wait_time);
+ if (splash->progress)
+ ply_progress_unpause (splash->progress);
}
void
return;
}
- splash->wait_time = ply_get_timestamp ();
+ if (splash->progress)
+ ply_progress_pause (splash->progress);
+
ply_trigger_add_handler (trigger,
(ply_trigger_handler_t)
on_password_answered, splash);