diff --git a/libc/wqueue/work_queue.c b/libc/wqueue/work_queue.c index 282e6cc024..5b9a0ac3e4 100644 --- a/libc/wqueue/work_queue.c +++ b/libc/wqueue/work_queue.c @@ -95,6 +95,17 @@ static int work_qqueue(FAR struct usr_wqueue_s *wqueue, while (work_lock() < 0); + /* Is there already pending work? */ + + if (work->worker != NULL) + { + /* Remove the entry from the work queue. It will re requeued at the + * end of the work queue. + */ + + dq_rem((FAR dq_entry_t *)work, &wqueue->q); + } + /* Initialize the work structure */ work->worker = worker; /* Work callback. non-NULL means queued */ @@ -150,12 +161,6 @@ int work_queue(int qid, FAR struct work_s *work, worker_t worker, { if (qid == USRWORK) { - /* Cancel any pending work in the work stucture */ - - (void)work_cancel(qid, work); - - /* Then queue the new work */ - return work_qqueue(&g_usrwork, work, worker, arg, delay); } else diff --git a/sched/wqueue/kwork_queue.c b/sched/wqueue/kwork_queue.c index 4b8137d42b..8b5a8e6f5a 100644 --- a/sched/wqueue/kwork_queue.c +++ b/sched/wqueue/kwork_queue.c @@ -94,12 +94,25 @@ static void work_qqueue(FAR struct kwork_wqueue_s *wqueue, DEBUGASSERT(work != NULL && worker != NULL); - /* First, initialize the work structure. This must be done with interrupts - * disabled. This permits this function to be called from with task logic - * or interrupt handlers. + /* Interrupts are disabled so that this logic can be called from with task + * logic or ifrom nterrupt handling logic. */ - flags = enter_critical_section(); + flags = enter_critical_section(); + + /* Is there already pending work? */ + + if (work->worker != NULL) + { + /* Remove the entry from the work queue. It will re requeued at the + * end of the work queue. + */ + + dq_rem((FAR dq_entry_t *)work, &wqueue->q); + } + + /* Initialize the work structure. */ + work->worker = worker; /* Work callback. non-NULL means queued */ work->arg = arg; /* Callback argument */ work->delay = delay; /* Delay until work performed */ @@ -149,11 +162,7 @@ static void work_qqueue(FAR struct kwork_wqueue_s *wqueue, int work_queue(int qid, FAR struct work_s *work, worker_t worker, FAR void *arg, systime_t delay) { - /* Cancel any pending work in the work stucture */ - - (void)work_cancel(qid, work); - - /* Then queue the new work */ + /* Queue the new work */ #ifdef CONFIG_SCHED_HPWORK if (qid == HPWORK)