diff options
author | Jose Bollo <jose.bollo@iot.bzh> | 2019-11-06 11:12:16 +0100 |
---|---|---|
committer | Jan-Simon Moeller <jsmoeller@linuxfoundation.org> | 2019-11-06 11:07:57 +0000 |
commit | 355db4b7f226c198fd001c41a0f3827dee65932f (patch) | |
tree | 560536ad63d0bb464cca11d0038be1f2ac897d58 | |
parent | b612db216c2793c34e264254794db3308d20d796 (diff) |
jobs: Fix callsync hanging
The function implementing jobs_enter, used by
implementations of synchronous calls, was not
taking care of waking up a thread. This had the
effect of blocking calls made by an external thread.
Bug-AGL: SPEC-2937
Change-Id: I4bf0265b4c029fb619ef7128824ee9d46a45996e
Signed-off-by: Jose Bollo <jose.bollo@iot.bzh>
-rw-r--r-- | src/jobs.c | 73 |
1 files changed, 48 insertions, 25 deletions
@@ -502,7 +502,7 @@ static int start_one_thread() * @param start The start mode for threads * @return 0 in case of success or -1 in case of error */ -static int queue_job( +static int queue_job_internal( const void *group, int timeout, void (*callback)(int, void*), @@ -512,8 +512,6 @@ static int queue_job( struct job *job; int rc, busy; - pthread_mutex_lock(&mutex); - /* check availability */ if (remaining_job_count <= 0) { ERROR("can't process job with threads: too many jobs"); @@ -548,16 +546,13 @@ static int queue_job( if (busy) evloop_wakeup(); - /* signal an existing job */ pthread_cond_signal(&cond); - pthread_mutex_unlock(&mutex); return 0; error2: job->next = first_free_job; first_free_job = job; error: - pthread_mutex_unlock(&mutex); return -1; } @@ -576,6 +571,40 @@ error: * The remaining parameter is the parameter 'arg1' * given here. * @param arg The second argument for 'callback' + * @param start The start mode for threads + * @return 0 in case of success or -1 in case of error + */ +static int queue_job( + const void *group, + int timeout, + void (*callback)(int, void*), + void *arg, + enum start_mode start_mode) +{ + int rc; + + pthread_mutex_lock(&mutex); + rc = queue_job_internal(group, timeout, callback, arg, start_mode); + pthread_mutex_unlock(&mutex); + return rc; + +} + +/** + * Queues a new asynchronous job represented by 'callback' and 'arg' + * for the 'group' and the 'timeout'. + * Jobs are queued FIFO and are possibly executed in parallel + * concurrently except for job of the same group that are + * executed sequentially in FIFO order. + * @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_queue( @@ -673,30 +702,24 @@ static int do_sync( struct sync *sync ) { - struct job *job; + int rc; pthread_mutex_lock(&mutex); - /* allocates the job */ - job = job_create(group, timeout, sync_cb, sync); - if (!job) { - pthread_mutex_unlock(&mutex); - return -1; + rc = queue_job_internal(group, timeout, sync_cb, sync, Start_Default); + if (rc == 0) { + /* run until stopped */ + if (current_thread) + thread_run_internal(&sync->thread); + else + thread_run_external(&sync->thread); + if (!sync->thread.leaved) { + errno = EINTR; + rc = -1; + } } - - /* queues the job */ - job_add(job); - - /* run until stopped */ - if (current_thread) - thread_run_internal(&sync->thread); - else - thread_run_external(&sync->thread); pthread_mutex_unlock(&mutex); - if (sync->thread.leaved) - return 0; - errno = EINTR; - return -1; + return rc; } /** |