mirror of
https://github.com/apache/nuttx.git
synced 2026-09-21 21:47:28 +08:00
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:
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
* 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 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
|
||||
* from the queue, or (2) work_cancel() has been called to cancel the work
|
||||
* and remove it from the work queue.
|
||||
@@ -91,6 +91,10 @@ static int work_qqueue(FAR struct usr_wqueue_s *wqueue,
|
||||
{
|
||||
DEBUGASSERT(work != NULL);
|
||||
|
||||
/* Cancel any pending work in the work stucture */
|
||||
|
||||
work_cancel(qid, work);
|
||||
|
||||
/* Get exclusive access to the work queue */
|
||||
|
||||
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
|
||||
* 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 queue logic. The caller should never modify the contents of
|
||||
* the work queue structure; the caller should not call work_queue()
|
||||
* 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
|
||||
* 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 work_queue() is called before the
|
||||
* previous work as been performed and removed from the queue, then any
|
||||
* pending work will be canceled and lost.
|
||||
*
|
||||
* Input parameters:
|
||||
* qid - The work queue ID (index)
|
||||
|
||||
Reference in New Issue
Block a user