13022591351 commented on code in PR #19982:
URL: https://github.com/apache/nuttx/pull/19982#discussion_r3891028311
##########
sched/wqueue/kwork_cancel.c:
##########
@@ -46,63 +47,65 @@ static int work_qcancel(FAR struct kwork_wqueue_s *wqueue,
bool sync,
FAR struct work_s *work)
{
irqstate_t flags;
- FAR sem_t *sync_wait = NULL;
+ pid_t self = sync ? nxsched_gettid() : INVALID_PROCESS_ID;
if (wqueue == NULL || work == NULL)
{
return -EINVAL;
}
- /* Cancelling the work is simply a matter of removing the work structure
- * from the work queue. This must be done with interrupts disabled because
- * new work is typically added to the work queue from interrupt handlers.
- */
-
- flags = spin_lock_irqsave(&wqueue->lock);
-
- if (!work_available(work))
+ for (; ; )
Review Comment:
The loop is required for a multi-worker queue. A work_s becomes available
for requeue after a worker dequeues it and clears work->worker, before the
callback returns. The same work_s can therefore be queued again and dispatched
to another worker while an earlier callback is still running.
Each iteration registers a waiter for one worker using this work_s, waits
for that callback to finish, and then rescans the worker pool until no other
callback is using it. The calling worker itself is excluded to avoid
self-deadlock. Without the loop, synchronous cancellation could return after
waiting for only one of several concurrent callbacks.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]