diff options
author | José Bollo <jose.bollo@iot.bzh> | 2017-04-06 10:31:09 +0200 |
---|---|---|
committer | José Bollo <jose.bollo@iot.bzh> | 2017-04-06 10:31:28 +0200 |
commit | c186dfbdbd43f5b51a67812ad48e1df1eacf131e (patch) | |
tree | 595464a4028f6d548260323120efa0c233adb12c | |
parent | 9fe2dfd3c4df334607083f989346090e1051a565 (diff) |
Add an easy function for synchronous calls
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 <jose.bollo@iot.bzh>
-rw-r--r-- | src/jobs.c | 72 | ||||
-rw-r--r-- | src/jobs.h | 6 |
2 files changed, 74 insertions, 4 deletions
@@ -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; @@ -621,6 +647,44 @@ int jobs_leave(struct jobloop *jobloop) } /** + * 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 */ @@ -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(); |