mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 08:36:24 +08:00
wqueue: fix assert about work was cancelled when work doesn't occur.
N/A Change-Id: I04916e041b1b3329287214c052d3ba5fc259235c Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
@@ -87,6 +87,17 @@ static int work_qcancel(FAR struct kwork_wqueue_s *wqueue,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The sem_wait() can't call from interrupt handlers, so worker
|
||||
* thread will still be awakened even if the work cancel is
|
||||
* called in interrupt handlers, but work thread can handle
|
||||
* this case with work empty in the work queue.
|
||||
*/
|
||||
|
||||
if (up_interrupt_context() == false)
|
||||
{
|
||||
nxsem_wait(&wqueue->sem);
|
||||
}
|
||||
|
||||
sq_rem((FAR sq_entry_t *)work, &wqueue->q);
|
||||
}
|
||||
|
||||
|
||||
+12
-19
@@ -118,6 +118,8 @@ static int work_thread(int argc, FAR char *argv[])
|
||||
wqueue = (FAR struct kwork_wqueue_s *)
|
||||
((uintptr_t)strtoul(argv[1], NULL, 0));
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Loop forever */
|
||||
|
||||
for (; ; )
|
||||
@@ -129,8 +131,6 @@ static int work_thread(int argc, FAR char *argv[])
|
||||
|
||||
nxsem_wait_uninterruptible(&wqueue->sem);
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* And check each entry in the work queue. Since we have disabled
|
||||
* interrupts we know: (1) we will not be suspended unless we do
|
||||
* so ourselves, and (2) there will be no changes to the work queue
|
||||
@@ -139,20 +139,14 @@ static int work_thread(int argc, FAR char *argv[])
|
||||
/* Remove the ready-to-execute work from the list */
|
||||
|
||||
work = (FAR struct work_s *)sq_remfirst(&wqueue->q);
|
||||
DEBUGASSERT(work);
|
||||
|
||||
/* Extract the work description from the entry (in case the work
|
||||
* instance by the re-used after it has been de-queued).
|
||||
*/
|
||||
|
||||
worker = work->worker;
|
||||
|
||||
/* Check for a race condition where the work may be nullified
|
||||
* before it is removed from the queue.
|
||||
*/
|
||||
|
||||
if (worker != NULL)
|
||||
if (work && work->worker)
|
||||
{
|
||||
/* Extract the work description from the entry (in case the work
|
||||
* instance by the re-used after it has been de-queued).
|
||||
*/
|
||||
|
||||
worker = work->worker;
|
||||
|
||||
/* Extract the work argument (before re-enabling interrupts) */
|
||||
|
||||
arg = work->arg;
|
||||
@@ -167,13 +161,12 @@ static int work_thread(int argc, FAR char *argv[])
|
||||
|
||||
leave_critical_section(flags);
|
||||
CALL_WORKER(worker, arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
leave_critical_section(flags);
|
||||
flags = enter_critical_section();
|
||||
}
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
||||
return OK; /* To keep some compilers happy */
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user