From ee9ec9d3bf22d479458deaafea8e5c9ca1e6c5eb Mon Sep 17 00:00:00 2001 From: "yuhong.tao@intel.com" Date: Tue, 26 Jun 2018 21:55:51 +0800 Subject: [PATCH] tools: acrnd: the acrnd work list Acrnd can and put delayed work functions in a work list. Reviewed-by: Yan Like Signed-off-by: Tao Yuhong --- tools/acrn-manager/acrnd.c | 89 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/tools/acrn-manager/acrnd.c b/tools/acrn-manager/acrnd.c index 5e71ea8d6..f87333e51 100644 --- a/tools/acrn-manager/acrnd.c +++ b/tools/acrn-manager/acrnd.c @@ -19,6 +19,89 @@ #include "acrn_mngr.h" #include "ioc.h" +/* acrnd worker timer */ + +struct work_arg { + char name[VMNAME_LEN]; +}; + +struct acrnd_work { + void (*func) (struct work_arg *arg); + time_t expire; /* when execute this work */ + + struct work_arg arg; + + LIST_ENTRY(acrnd_work) list; +}; + +static LIST_HEAD(acrnd_work_list, acrnd_work) work_head; +static pthread_mutex_t work_mutex = PTHREAD_MUTEX_INITIALIZER; + +/* acrnd_add_work(), add a worker function. + * @func, the worker function. + * @sec, when add a @func(), after @sec seconds @func() will be called. + * @arg, a cpoy of @arg will be pass to @func. + */ +int acrnd_add_work(void (*func) (struct work_arg *arg), + struct work_arg *arg, unsigned sec) +{ + struct acrnd_work *work; + time_t current; + + if (!func) { + pdebug(); + return -1; + } + + work = calloc(1, sizeof(*work)); + if (!work) { + perror("Alloc work struct fail:"); + return -1; + } + + current = time(NULL); + if (current == (time_t) - 1) { + perror("Get current time by timer() fail:"); + free(work); + return -1; + } + + work->func = func; + work->expire = sec + current; + if (arg) + memcpy(&work->arg, arg, sizeof(*arg)); + + pthread_mutex_lock(&work_mutex); + LIST_INSERT_HEAD(&work_head, work, list); + pthread_mutex_unlock(&work_mutex); + return 0; +} + +/* check if the works in work_head is expired, if expired then run + * work func() once and delete it + */ +static void try_do_works(void) +{ + time_t current; + struct acrnd_work *work, *twork; + + current = time(NULL); + if (current == (time_t) - 1) { + perror("Get current time by timer() fail:"); + return; + } + + list_foreach_safe(work, &work_head, list, twork) { + if (current > work->expire) { + pthread_mutex_lock(&work_mutex); + work->func(&work->arg); + LIST_REMOVE(work, list); + pthread_mutex_unlock(&work_mutex); + free(work); + } + } +} + #define TIMER_LIST_FILE "/opt/acrn/conf/timer_list" /* load/store_timer_list to file to keep timers if SOS poweroff */ @@ -252,5 +335,11 @@ int main(int argc, char *argv[]) mngr_add_handler(acrnd_fd, ACRND_STOP, handle_acrnd_stop, NULL); mngr_add_handler(acrnd_fd, ACRND_RESUME, handle_acrnd_resume, NULL); + /* Last thing, run our timer works */ + while (1) { + try_do_works(); + sleep(1); + } + return 0; }