work_queue() must cancel existing work prior to queuing new work, otherwise the work queue can become corrupted. Problem noted by Pascal Speck.
This commit is contained in:
parent
809569cda9
commit
bbf4d5048a
@ -2954,7 +2954,10 @@ int work_queue(int qid, FAR struct work_s *work, worker_t worker,
|
|||||||
Queue work to be performed at a later time. All queued work will be performed on the worker thread of execution (not the caller's).
|
Queue work to be performed at a later time. All queued work will be performed on the worker thread of execution (not the caller's).
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
The work structure is allocated by caller, but completely managed by the work queue logic. The caller should never modify the contents of the work queue structure; the caller should not call <code>work_queue()</code> again until either (1) the previous work has been performed and removed from the queue, or (2) <code>work_cancel()</code> has been called to cancel the work and remove it from the work queue.
|
The work structure is allocated and must be initialized to all zero by the caller.
|
||||||
|
Otherwise, the work structure is completely managed by the work queue logic.
|
||||||
|
The caller should never modify the contents of the work queue structure directly.
|
||||||
|
If <code>work_queue()</code> is called before the previous work as been performed and removed from the queue, then any pending work will be canceled and lost.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<b>Input Parameters</b>:
|
<b>Input Parameters</b>:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* include/nuttx/wqueue.h
|
* include/nuttx/wqueue.h
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009, 2011-2014 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2009, 2011-2014, 2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -338,12 +338,12 @@ int work_usrstart(void);
|
|||||||
* Queue work to be performed at a later time. All queued work will be
|
* Queue work to be performed at a later time. All queued work will be
|
||||||
* performed on the worker thread of execution (not the caller's).
|
* performed on the worker thread of execution (not the caller's).
|
||||||
*
|
*
|
||||||
* The work structure is allocated by caller, but completely managed by
|
* The work structure is allocated and must be initialized to all zero by
|
||||||
* the work queue logic. The caller should never modify the contents of
|
* the caller. Otherwise, the work structure is completely managed by the
|
||||||
* the work queue structure; the caller should not call work_queue()
|
* work queue logic. The caller should never modify the contents of the
|
||||||
* again until either (1) the previous work has been performed and removed
|
* work queue structure directly. If work_queue() is called before the
|
||||||
* from the queue, or (2) work_cancel() has been called to cancel the work
|
* previous work as been performed and removed from the queue, then any
|
||||||
* and remove it from the work queue.
|
* pending work will be canceled and lost.
|
||||||
*
|
*
|
||||||
* Input parameters:
|
* Input parameters:
|
||||||
* qid - The work queue ID
|
* qid - The work queue ID
|
||||||
|
@ -50,22 +50,6 @@
|
|||||||
|
|
||||||
#if defined(CONFIG_LIB_USRWORK) && !defined(__KERNEL__)
|
#if defined(CONFIG_LIB_USRWORK) && !defined(__KERNEL__)
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Pre-processor Definitions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Type Declarations
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Public Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* libc/wqueue/work_queue.c
|
* libc/wqueue/work_queue.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009-2011, 2014, 2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2009-2011, 2014, 2016-2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -65,7 +65,7 @@
|
|||||||
*
|
*
|
||||||
* The work structure is allocated by caller, but completely managed by
|
* The work structure is allocated by caller, but completely managed by
|
||||||
* the work queue logic. The caller should never modify the contents of
|
* the work queue logic. The caller should never modify the contents of
|
||||||
* the work queue structure; the caller should not call work_queue()
|
* the work queue structure; the caller should not call work_qqueue()
|
||||||
* again until either (1) the previous work has been performed and removed
|
* again until either (1) the previous work has been performed and removed
|
||||||
* from the queue, or (2) work_cancel() has been called to cancel the work
|
* from the queue, or (2) work_cancel() has been called to cancel the work
|
||||||
* and remove it from the work queue.
|
* and remove it from the work queue.
|
||||||
@ -91,6 +91,10 @@ static int work_qqueue(FAR struct usr_wqueue_s *wqueue,
|
|||||||
{
|
{
|
||||||
DEBUGASSERT(work != NULL);
|
DEBUGASSERT(work != NULL);
|
||||||
|
|
||||||
|
/* Cancel any pending work in the work stucture */
|
||||||
|
|
||||||
|
work_cancel(qid, work);
|
||||||
|
|
||||||
/* Get exclusive access to the work queue */
|
/* Get exclusive access to the work queue */
|
||||||
|
|
||||||
while (work_lock() < 0);
|
while (work_lock() < 0);
|
||||||
@ -123,12 +127,12 @@ static int work_qqueue(FAR struct usr_wqueue_s *wqueue,
|
|||||||
* Queue user-mode work to be performed at a later time. All queued work
|
* Queue user-mode work to be performed at a later time. All queued work
|
||||||
* will be performed on the worker thread of of execution (not the caller's).
|
* will be performed on the worker thread of of execution (not the caller's).
|
||||||
*
|
*
|
||||||
* The work structure is allocated by caller, but completely managed by
|
* The work structure is allocated and must be initialized to all zero by
|
||||||
* the work queue logic. The caller should never modify the contents of
|
* the caller. Otherwise, the work structure is completely managed by the
|
||||||
* the work queue structure; the caller should not call work_queue()
|
* work queue logic. The caller should never modify the contents of the
|
||||||
* again until either (1) the previous work has been performed and removed
|
* work queue structure directly. If work_queue() is called before the
|
||||||
* from the queue, or (2) work_cancel() has been called to cancel the work
|
* previous work as been performed and removed from the queue, then any
|
||||||
* and remove it from the work queue.
|
* pending work will be canceled and lost.
|
||||||
*
|
*
|
||||||
* Input parameters:
|
* Input parameters:
|
||||||
* qid - The work queue ID (index)
|
* qid - The work queue ID (index)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/wqueue/kwork_queue.c
|
* sched/wqueue/kwork_queue.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2014, 2016-2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -66,7 +66,7 @@
|
|||||||
*
|
*
|
||||||
* The work structure is allocated by caller, but completely managed by
|
* The work structure is allocated by caller, but completely managed by
|
||||||
* the work queue logic. The caller should never modify the contents of
|
* the work queue logic. The caller should never modify the contents of
|
||||||
* the work queue structure; the caller should not call work_queue()
|
* the work queue structure; the caller should not call work_qqueue()
|
||||||
* again until either (1) the previous work has been performed and removed
|
* again until either (1) the previous work has been performed and removed
|
||||||
* from the queue, or (2) work_cancel() has been called to cancel the work
|
* from the queue, or (2) work_cancel() has been called to cancel the work
|
||||||
* and remove it from the work queue.
|
* and remove it from the work queue.
|
||||||
@ -124,12 +124,12 @@ static void work_qqueue(FAR struct kwork_wqueue_s *wqueue,
|
|||||||
* Queue kernel-mode work to be performed at a later time. All queued work
|
* Queue kernel-mode work to be performed at a later time. All queued work
|
||||||
* will be performed on the worker thread of of execution (not the caller's).
|
* will be performed on the worker thread of of execution (not the caller's).
|
||||||
*
|
*
|
||||||
* The work structure is allocated by caller, but completely managed by
|
* The work structure is allocated and must be initialized to all zero by
|
||||||
* the work queue logic. The caller should never modify the contents of
|
* the caller. Otherwise, the work structure is completely managed by the
|
||||||
* the work queue structure; the caller should not call work_queue()
|
* work queue logic. The caller should never modify the contents of the
|
||||||
* again until either (1) the previous work has been performed and removed
|
* work queue structure directly. If work_queue() is called before the
|
||||||
* from the queue, or (2) work_cancel() has been called to cancel the work
|
* previous work as been performed and removed from the queue, then any
|
||||||
* and remove it from the work queue.
|
* pending work will be canceled and lost.
|
||||||
*
|
*
|
||||||
* Input parameters:
|
* Input parameters:
|
||||||
* qid - The work queue ID (index)
|
* qid - The work queue ID (index)
|
||||||
@ -149,6 +149,12 @@ static void work_qqueue(FAR struct kwork_wqueue_s *wqueue,
|
|||||||
int work_queue(int qid, FAR struct work_s *work, worker_t worker,
|
int work_queue(int qid, FAR struct work_s *work, worker_t worker,
|
||||||
FAR void *arg, systime_t delay)
|
FAR void *arg, systime_t delay)
|
||||||
{
|
{
|
||||||
|
/* Cancel any pending work in the work stucture */
|
||||||
|
|
||||||
|
work_cancel(qid, work);
|
||||||
|
|
||||||
|
/* Then queue the new work */
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_HPWORK
|
#ifdef CONFIG_SCHED_HPWORK
|
||||||
if (qid == HPWORK)
|
if (qid == HPWORK)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user