summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2017-04-06 10:31:09 +0200
committerJosé Bollo <jose.bollo@iot.bzh>2017-04-06 10:31:28 +0200
commitc186dfbdbd43f5b51a67812ad48e1df1eacf131e (patch)
tree595464a4028f6d548260323120efa0c233adb12c
parent9fe2dfd3c4df334607083f989346090e1051a565 (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.c72
-rw-r--r--src/jobs.h6
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;
@@ -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
*/
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();