Commit fe76f3bf authored by Christian Hergert's avatar Christian Hergert

generator: add threading and async API

By using an async API for generation, we allow ourselves to run
the generators in a thread-pool, giving ourselves a chance at a
healthy speed up in generation.
parent 4468ac6f
...@@ -310,25 +310,55 @@ girst_generator_generate_repository (GirstGenerator *self, ...@@ -310,25 +310,55 @@ girst_generator_generate_repository (GirstGenerator *self,
return TRUE; return TRUE;
} }
gboolean static void
girst_generator_generate (GirstGenerator *self, girst_generator_generate_worker (GTask *task,
GCancellable *cancellable, gpointer source_object,
GError **error) gpointer task_data,
GCancellable *cancellable)
{ {
g_return_val_if_fail (GIRST_IS_GENERATOR (self), FALSE); GirstGenerator *self = source_object;
g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE); g_autoptr(GError) error = NULL;
g_assert (G_IS_TASK (task));
g_assert (GIRST_IS_GENERATOR (self));
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
errno = 0;
if (g_mkdir_with_parents (self->outdir, 0750) != 0) if (g_mkdir_with_parents (self->outdir, 0750) != 0)
{ g_task_return_new_error (task,
g_set_error_literal (error, G_FILE_ERROR,
G_FILE_ERROR, g_file_error_from_errno (errno),
g_file_error_from_errno (errno), "%s", g_strerror (errno));
g_strerror (errno));
return FALSE; if (!girst_generator_generate_repository (self, self->repository, &error))
} g_task_return_error (task, g_steal_pointer (&error));
else
g_task_return_boolean (task, TRUE);
}
if (!girst_generator_generate_repository (self, self->repository, error)) void
return FALSE; girst_generator_generate_async (GirstGenerator *self,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_autoptr(GTask) task = NULL;
return TRUE; g_return_if_fail (GIRST_IS_GENERATOR (self));
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
task = g_task_new (self, cancellable, callback, user_data);
g_task_set_source_tag (task, girst_generator_generate_async);
g_task_run_in_thread (task, girst_generator_generate_worker);
}
gboolean
girst_generator_generate_finish (GirstGenerator *self,
GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (GIRST_IS_GENERATOR (self), FALSE);
g_return_val_if_fail (G_IS_TASK (result), FALSE);
return g_task_propagate_boolean (G_TASK (result), error);
} }
...@@ -27,11 +27,15 @@ G_BEGIN_DECLS ...@@ -27,11 +27,15 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (GirstGenerator, girst_generator, GIRST, GENERATOR, GObject) G_DECLARE_FINAL_TYPE (GirstGenerator, girst_generator, GIRST, GENERATOR, GObject)
GirstGenerator *girst_generator_new (GirstRepository *repository, GirstGenerator *girst_generator_new (GirstRepository *repository,
const gchar *outdir, const gchar *outdir,
GirstLanguage language); GirstLanguage language);
gboolean girst_generator_generate (GirstGenerator *self, void girst_generator_generate_async (GirstGenerator *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GAsyncReadyCallback callback,
gpointer user_data);
gboolean girst_generator_generate_finish (GirstGenerator *self,
GAsyncResult *result,
GError **error);
G_END_DECLS G_END_DECLS
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
static gchar *language; static gchar *language;
static gchar *outdir; static gchar *outdir;
static gchar **girdirs; static gchar **girdirs;
static gint exit_code = EXIT_SUCCESS;
static gint active;
static const GOptionEntry main_entries[] = { static const GOptionEntry main_entries[] = {
{ "outdir", 'o', 0, G_OPTION_ARG_FILENAME, &outdir, { "outdir", 'o', 0, G_OPTION_ARG_FILENAME, &outdir,
"Location to store generated files", "Location to store generated files",
...@@ -45,6 +47,27 @@ static const GOptionEntry main_entries[] = { ...@@ -45,6 +47,27 @@ static const GOptionEntry main_entries[] = {
{ NULL } { NULL }
}; };
static void
girst_main_generate_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
GirstGenerator *generator = (GirstGenerator *)object;
g_autoptr(GMainLoop) main_loop = user_data;
g_autoptr(GError) error = NULL;
g_assert (GIRST_IS_GENERATOR (generator));
g_assert (main_loop != NULL);
if (!girst_generator_generate_finish (generator, result, &error))
g_error ("%s", error->message);
active--;
if (active == 0)
g_main_loop_quit (main_loop);
}
static void static void
foreach_repository_cb (gpointer data, foreach_repository_cb (gpointer data,
gpointer user_data) gpointer user_data)
...@@ -52,23 +75,18 @@ foreach_repository_cb (gpointer data, ...@@ -52,23 +75,18 @@ foreach_repository_cb (gpointer data,
g_autoptr(GirstGenerator) generator = NULL; g_autoptr(GirstGenerator) generator = NULL;
GirstRepository *repository = data; GirstRepository *repository = data;
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
gint *exit_code = user_data; GMainLoop *main_loop = user_data;
g_assert (GIRST_IS_REPOSITORY (repository)); g_assert (GIRST_IS_REPOSITORY (repository));
g_assert (exit_code != NULL); g_assert (main_loop != NULL);
if (*exit_code != EXIT_SUCCESS) active++;
return;
generator = girst_generator_new (repository, outdir, GIRST_LANGUAGE_C); generator = girst_generator_new (repository, outdir, GIRST_LANGUAGE_C);
girst_generator_generate_async (generator,
if (!girst_generator_generate (generator, NULL, &error)) NULL,
{ girst_main_generate_cb,
g_printerr ("Error processing %s: %s\n", g_main_loop_ref (main_loop));
(gchar *)g_object_get_data (G_OBJECT (repository), "NAME"),
error->message);
*exit_code = EXIT_FAILURE;
}
} }
static GFile * static GFile *
...@@ -148,7 +166,7 @@ main (gint argc, ...@@ -148,7 +166,7 @@ main (gint argc,
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
g_autoptr(GHashTable) loaded = NULL; g_autoptr(GHashTable) loaded = NULL;
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
gint exit_code = EXIT_SUCCESS; g_autoptr(GMainLoop) main_loop = NULL;
girst_parser_ensure_types (); girst_parser_ensure_types ();
...@@ -174,6 +192,8 @@ main (gint argc, ...@@ -174,6 +192,8 @@ main (gint argc,
return EXIT_FAILURE; return EXIT_FAILURE;
} }
main_loop = g_main_loop_new (NULL, FALSE);
g_irepository_prepend_search_path ("."); g_irepository_prepend_search_path (".");
g_irepository_require (g_irepository_get_default (), "Girst", "1.0", 0, NULL); g_irepository_require (g_irepository_get_default (), "Girst", "1.0", 0, NULL);
...@@ -223,7 +243,9 @@ main (gint argc, ...@@ -223,7 +243,9 @@ main (gint argc,
} }
} }
girst_cache_foreach (foreach_repository_cb, &exit_code); girst_cache_foreach (foreach_repository_cb, main_loop);
g_main_loop_run (main_loop);
return exit_code; return exit_code;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment