From a56e676b68dce3c080e4dd9f4af3698cf6a69a67 Mon Sep 17 00:00:00 2001 From: Julio Montes Date: Wed, 3 Feb 2016 16:09:52 -0600 Subject: [PATCH] use async_task functions add async_task to unit tests --- src/disk.c | 5 +- src/disk.h | 2 +- src/main.c | 147 +++++++--------------------------------------- tests/Makefile.am | 1 + 4 files changed, 26 insertions(+), 129 deletions(-) diff --git a/src/disk.c b/src/disk.c index bbe385d..5cf0a9d 100644 --- a/src/disk.c +++ b/src/disk.c @@ -43,6 +43,7 @@ #include #include "lib.h" +#include "async_task.h" #define MOD "disk: " @@ -83,7 +84,7 @@ char *disk_by_path(const gchar* path) { return blkid_devno_to_devname(disk); } -gboolean disk_fix(const gchar* disk_path, GChildWatchFunc async_func_watcher, gpointer data) { +gboolean disk_fix(const gchar* disk_path) { char command[LINE_MAX] = { 0 }; int last_partition_num; const gchar* partition_path; @@ -182,7 +183,7 @@ gboolean disk_fix(const gchar* disk_path, GChildWatchFunc async_func_watcher, gp } snprintf(command, LINE_MAX, RESIZEFS_PATH " %s", partition_path); - exec_task_async(command, async_func_watcher, data); + async_task_exec(command); result = true; LOG(MOD "Resizing filesystem done\n"); diff --git a/src/disk.h b/src/disk.h index 8b848a1..6f7a228 100644 --- a/src/disk.h +++ b/src/disk.h @@ -37,7 +37,7 @@ char *disk_by_path(const gchar* path); -gboolean disk_fix(const gchar* disk_path, GChildWatchFunc async_func_watcher, gpointer data); +gboolean disk_fix(const gchar* disk_path); gboolean disk_by_label(const gchar* label, gchar** device); diff --git a/src/main.c b/src/main.c index 045c1b8..d848894 100644 --- a/src/main.c +++ b/src/main.c @@ -55,6 +55,7 @@ #include "datasources.h" #include "default_user.h" #include "openstack.h" +#include "async_task.h" /* Long options */ @@ -85,53 +86,26 @@ static struct option opts[] = { { NULL, 0, NULL, 0 } }; -typedef bool (*async_task_function) (gpointer); - -static struct async_data { - GMainLoop* main_loop; - guint remaining; -} async_data; - -static void async_process_watcher(GPid pid, gint status, gpointer _data) { - struct async_data* data = (struct async_data*)_data; - - LOG("PID %d ends, exit status %d\n", pid, status); - - --(data->remaining); - - if (0 == data->remaining) { - LOG("Quit main loop\n"); - g_main_loop_quit(data->main_loop); - } - - if (pid != 0) { - g_spawn_close_pid(pid); - } -} - -bool async_fixdisk(gpointer data) { +static int async_fixdisk(__unused__ gpointer null) { char* root_disk; - bool result = false; root_disk = disk_by_path("/"); - if (root_disk) { - LOG("Checking disk %s\n", root_disk); - if (!disk_fix(root_disk, async_process_watcher, data)) { - goto fail; - } - } else { + if (!root_disk) { LOG("Root disk not found\n"); - return false; + return 1; } - result = true; + LOG("Checking disk %s\n", root_disk); + if (!disk_fix(root_disk)) { + free(root_disk); + return 1; + } -fail: free(root_disk); - return result; + return 0; } -bool async_setup_first_boot(gpointer data) { +static bool async_setup_first_boot(__unused__ gpointer null) { gchar command[LINE_MAX] = { 0 }; GString* sudo_directives = NULL; @@ -145,58 +119,7 @@ bool async_setup_first_boot(gpointer data) { /* lock root account for security */ g_snprintf(command, LINE_MAX, USERMOD_PATH " -p '!' root"); - return exec_task_async(command, async_process_watcher, data); -} - -static void run_task(gpointer function, gpointer data) { - async_task_function func = *(async_task_function*)(&function); - if ( ! func(data) ) { - async_process_watcher(0, 0, data); - } -} - -static void async_item(gpointer function, gpointer thread_pool) { - GError *error = NULL; - - ++(async_data.remaining); - - g_thread_pool_push((GThreadPool*)thread_pool, function, &error); - if (error) { - LOG("Error pushing a new thread: %s\n", (char*)error->message); - g_error_free(error); - } -} - -static gint run_async_tasks(GPtrArray* async_tasks_array) { - gint result_code = EXIT_FAILURE; - GThreadPool* thread_pool = NULL; - - async_data.main_loop = g_main_loop_new(NULL, 0); - if (!async_data.main_loop) { - LOG("Cannot create a new main loop\n"); - goto fail1; - } - - thread_pool = g_thread_pool_new(run_task, &async_data, get_nprocs(), true, NULL); - if (!thread_pool) { - LOG("Cannot create a new thread pool\n"); - goto fail2; - } - - //push threads to pool - g_ptr_array_foreach(async_tasks_array, async_item, thread_pool); - - //run main loop to wait the end of async tasks - g_main_loop_run(async_data.main_loop); - - result_code = EXIT_SUCCESS; - - g_thread_pool_free(thread_pool, false, true); - -fail2: - g_main_loop_unref(async_data.main_loop); -fail1: - return result_code; + return async_task_exec(command); } int main(int argc, char *argv[]) { @@ -216,11 +139,7 @@ int main(int argc, char *argv[]) { bool process_user_data_once = false; bool process_metadata = false; struct datasource_handler_struct *datasource_handler = NULL; - GError* error = NULL; - GThread* async_tasks_thread = NULL; - async_task_function func = NULL; gchar command[LINE_MAX] = { 0 }; - GPtrArray* async_tasks_array = NULL; while (true) { c = getopt_long(argc, argv, "u:hv", opts, &i); @@ -303,6 +222,10 @@ int main(int argc, char *argv[]) { LOG("Unable to create data dir '%s'\n", DATADIR_PATH); } + if (!async_task_init()) { + LOG("Unable to init async task\n"); + } + /* process specific metadata file */ if (tmp_metadata_filename) { if (realpath(tmp_metadata_filename, metadata_filename)) { @@ -357,36 +280,12 @@ int main(int argc, char *argv[]) { get_boot_info(&first_boot, &snapshot); } - async_tasks_array = g_ptr_array_new(); - if (!async_tasks_array) { - LOG("Unable to create a new ptr array for async tasks\n"); + if (fix_disk) { + async_task_run((GThreadFunc)async_fixdisk, NULL); } - if (fix_disk && async_tasks_array) { - func = async_fixdisk; - g_ptr_array_add(async_tasks_array, *(async_task_function**)&func); - } - - if (first_boot && async_tasks_array) { - func = async_setup_first_boot; - g_ptr_array_add(async_tasks_array, *(async_task_function**)&func); - } - - if (async_tasks_array && async_tasks_array->len > 0) { - if (get_nprocs() > 1) { - async_tasks_thread = g_thread_try_new("run_async_tasks", (GThreadFunc)run_async_tasks, - async_tasks_array, &error); - if (!async_tasks_thread) { - LOG("Cannot create a thread to run async tasks!"); - if (error) { - LOG("Error: %s\n", (char*)error->message); - g_error_free(error); - error = NULL; - } - } - } else { - run_async_tasks(async_tasks_array); - } + if (first_boot) { + async_task_run((GThreadFunc)async_setup_first_boot, NULL); } if (first_boot) { @@ -429,11 +328,7 @@ int main(int argc, char *argv[]) { datasource_handler->finish(); } - if (async_tasks_thread) { - g_thread_join(async_tasks_thread); - } - - g_ptr_array_unref(async_tasks_array); + async_task_finish(); exit(result_code); } diff --git a/tests/Makefile.am b/tests/Makefile.am index afb9929..8761134 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -17,6 +17,7 @@ COMMON_LDADD = $(CHECK_LIBS) $(GLIB_LIBS) $(CURL_LIBS) $(YAML_LIBS) $(BLKID_LIBS libtest_la_SOURCES = \ ../src/lib.c \ ../src/curl.c \ + ../src/async_task.c \ ../src/disk.c \ ../src/userdata.c \ ../src/interpreters/cloud_config.c \