#include #include "scheduler.h" #include "exactness_config.h" typedef struct { Scheduler_Cb prepare_func; List_Entry *last; unsigned short jobs; } Scheduler_Ctx; static Ecore_Event_Handler *_job_del_callback_handler = NULL; static Eina_Bool _job_dispatch(List_Entry *ent, Scheduler_Ctx *ctx); static Eina_Bool _job_deleted_cb(void *data, int type EINA_UNUSED, void *event) { Ecore_Exe_Event_Del *msg = (Ecore_Exe_Event_Del *) event; Scheduler_Ctx *ctx = data; if ((msg->exit_code != 0) || (msg->exit_signal != 0)) { List_Entry *ent = ecore_exe_data_get(msg->exe); exactness_ctx.errors = eina_list_append(exactness_ctx.errors, ent); } ctx->jobs++; exactness_ctx.tests_executed++; if (ctx->last && EINA_INLIST_GET(ctx->last)->next) { ctx->last = EINA_INLIST_CONTAINER_GET( EINA_INLIST_GET(ctx->last)->next, List_Entry); _job_dispatch(ctx->last, ctx); } /* If all jobs are done. */ if (ctx->jobs == exactness_config.jobs) { free(ctx); ecore_main_loop_quit(); return ECORE_CALLBACK_DONE; } return ECORE_CALLBACK_RENEW; } static Eina_Bool _job_dispatch(List_Entry *ent, Scheduler_Ctx *ctx) { char buf[SCHEDULER_CMD_SIZE]; Ecore_Exe *exe; if (ctx->jobs == 0) return EINA_FALSE; ctx->jobs--; ctx->prepare_func(ent, buf); if (!_job_del_callback_handler) { _job_del_callback_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _job_deleted_cb, ctx); } exe = ecore_exe_pipe_run(buf, ECORE_EXE_TERM_WITH_PARENT, ent); if (!exe) { fprintf(stderr, "Failed executing test '%s'\n", ent->name); } return EINA_TRUE; } void scheduler_run(Scheduler_Cb prepare_func, List_Entry *list) { Scheduler_Ctx *ctx = calloc(1, sizeof(*ctx)); List_Entry *list_itr; ctx->jobs = exactness_config.jobs; ctx->prepare_func = prepare_func; EINA_INLIST_FOREACH(list, list_itr) { if (!_job_dispatch(list_itr, ctx)) break; ctx->last = list_itr; } }