sched/wqueue: Fix unexpected dq entry status
When we do not drop notifier from g_notifier_pending, we need an isolated dq entry for this queue, otherwise the queued work_s's dq entry may be modified by the work queue and breaks the chain of g_notifier_pending. Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This commit is contained in:
parent
4d6203d4c6
commit
f8bd93575c
@ -53,10 +53,9 @@
|
|||||||
|
|
||||||
struct work_notifier_entry_s
|
struct work_notifier_entry_s
|
||||||
{
|
{
|
||||||
/* This must appear at the beginning of the structure. A reference to
|
struct dq_entry_s entry;
|
||||||
* the struct work_notifier_entry_s instance must be cast-compatible with
|
|
||||||
* struct dq_entry_s.
|
/* The work structure */
|
||||||
*/
|
|
||||||
|
|
||||||
struct work_s work; /* Used for scheduling the work */
|
struct work_s work; /* Used for scheduling the work */
|
||||||
|
|
||||||
@ -170,11 +169,11 @@ static void work_notifier_worker(FAR void *arg)
|
|||||||
|
|
||||||
/* Remove the notification from the pending list */
|
/* Remove the notification from the pending list */
|
||||||
|
|
||||||
dq_rem((FAR dq_entry_t *)notifier, &g_notifier_pending);
|
dq_rem(¬ifier->entry, &g_notifier_pending);
|
||||||
|
|
||||||
/* Put the notification to the free list */
|
/* Put the notification to the free list */
|
||||||
|
|
||||||
dq_addlast((FAR dq_entry_t *)notifier, &g_notifier_free);
|
dq_addlast(¬ifier->entry, &g_notifier_free);
|
||||||
|
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
}
|
}
|
||||||
@ -259,7 +258,7 @@ int work_notifier_setup(FAR struct work_notifier_s *info)
|
|||||||
* notifications executed in a saner order?
|
* notifications executed in a saner order?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dq_addlast((FAR dq_entry_t *)notifier, &g_notifier_pending);
|
dq_addlast(¬ifier->entry, &g_notifier_pending);
|
||||||
ret = notifier->key;
|
ret = notifier->key;
|
||||||
|
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
@ -308,11 +307,11 @@ void work_notifier_teardown(int key)
|
|||||||
{
|
{
|
||||||
/* Remove the notification from the pending list */
|
/* Remove the notification from the pending list */
|
||||||
|
|
||||||
dq_rem((FAR dq_entry_t *)notifier, &g_notifier_pending);
|
dq_rem(¬ifier->entry, &g_notifier_pending);
|
||||||
|
|
||||||
/* Put the notification to the free list */
|
/* Put the notification to the free list */
|
||||||
|
|
||||||
dq_addlast((FAR dq_entry_t *)notifier, &g_notifier_free);
|
dq_addlast(¬ifier->entry, &g_notifier_free);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user