From c186dfbdbd43f5b51a67812ad48e1df1eacf131e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Bollo?= Date: Thu, 6 Apr 2017 10:31:09 +0200 Subject: [PATCH] Add an easy function for synchronous calls MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The added function, 'jobs_call', allows to call a job with 'group' sequencing and 'timeout' handling synchronously. The difference with 'jobs_enter' is that the function 'jobs_call' assert that the job is terminated when 'callback' returns. Change-Id: I8c01d1cd017787ca0448b03a899305a9069ebb6c Signed-off-by: José Bollo --- src/jobs.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- src/jobs.h | 6 ++++++ 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/jobs.c b/src/jobs.c index 1ed20fcb..17deb88e 100644 --- a/src/jobs.c +++ b/src/jobs.c @@ -82,6 +82,15 @@ struct thread unsigned waits: 1; /**< is waiting? */ }; +/** + * Description of synchonous callback + */ +struct sync +{ + void (*callback)(int, void*); /**< the synchrnous callback */ + void *arg; /**< the argument of the callback */ +}; + /* synchronisation of threads */ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; @@ -451,7 +460,7 @@ int jobs_queue0( * or the signal number that broke the normal flow. * The remaining parameter is the parameter 'arg1' * given here. - * @param arg1 The second argument for 'callback' + * @param arg The second argument for 'callback' * @return 0 in case of success or -1 in case of error */ int jobs_queue( @@ -569,13 +578,25 @@ error: /** * Enter a synchronisation point: activates the job given by 'callback' - * @param group the gro + * and 'closure' using 'group' and 'timeout' to control sequencing and + * execution time. + * @param group the group for sequencing jobs + * @param timeout the time in seconds allocated to the job + * @param callback the callback that will handle the job. + * it receives 3 parameters: 'signum' that will be 0 + * on normal flow or the catched signal number in case + * of interrupted flow, the context 'closure' as given and + * a 'jobloop' reference that must be used when the job is + * terminated to unlock the current execution flow. + * @param closure the context completion closure for the callback + * @return 0 on success or -1 in case of error */ int jobs_enter( void *group, int timeout, void (*callback)(int signum, void *closure, struct jobloop *jobloop), - void *closure) + void *closure +) { struct job *job; @@ -601,11 +622,16 @@ int jobs_enter( return 0; } +/** + * Unlocks the execution flow designed by 'jobloop'. + * @param jobloop indication of the flow to unlock + * @return 0 in case of success of -1 on error + */ int jobs_leave(struct jobloop *jobloop) { struct thread *t; - pthread_mutex_lock(&mutex); + pthread_mutex_lock(&mutex); t = threads; while (t && t != (struct thread*)jobloop) t = t->next; @@ -620,6 +646,44 @@ int jobs_leave(struct jobloop *jobloop) return -!t; } +/** + * Internal helper function for 'jobs_call'. + * @see jobs_call, jobs_enter, jobs_leave + */ +static void call_cb(int signum, void *closure, struct jobloop *jobloop) +{ + struct sync *sync = closure; + sync->callback(signum, sync->arg); + jobs_leave(jobloop); +} + +/** + * Calls synchronously the job represented by 'callback' and 'arg1' + * for the 'group' and the 'timeout' and waits for its completion. + * @param group The group of the job or NULL when no group. + * @param timeout The maximum execution time in seconds of the job + * or 0 for unlimited time. + * @param callback The function to execute for achieving the job. + * Its first parameter is either 0 on normal flow + * or the signal number that broke the normal flow. + * The remaining parameter is the parameter 'arg1' + * given here. + * @param arg The second argument for 'callback' + * @return 0 in case of success or -1 in case of error + */ +int jobs_call( + void *group, + int timeout, + void (*callback)(int, void*), + void *arg) +{ + struct sync sync; + + sync.callback = callback; + sync.arg = arg; + return jobs_enter(group, timeout, call_cb, &sync); +} + /** * Gets a sd_event item for the current thread. * @return a sd_event or NULL in case of error diff --git a/src/jobs.h b/src/jobs.h index f508e3c0..a98b27ad 100644 --- a/src/jobs.h +++ b/src/jobs.h @@ -54,6 +54,12 @@ extern int jobs_enter( extern int jobs_leave(struct jobloop *jobloop); +extern int jobs_call( + void *group, + int timeout, + void (*callback)(int, void*), + void *arg); + extern struct sd_event *jobs_get_sd_event(); extern void jobs_terminate(); -- 2.16.6