diff --git a/Documentation/NuttxPortingGuide.html b/Documentation/NuttxPortingGuide.html index d5003860eef..12850ed4952 100644 --- a/Documentation/NuttxPortingGuide.html +++ b/Documentation/NuttxPortingGuide.html @@ -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).

- 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: diff --git a/include/nuttx/wqueue.h b/include/nuttx/wqueue.h index 59fa8f0a920..b5ee23e022a 100644 --- a/include/nuttx/wqueue.h +++ b/include/nuttx/wqueue.h @@ -1,7 +1,7 @@ /**************************************************************************** * 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 * * 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 * performed on the worker thread 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 diff --git a/libc/wqueue/work_cancel.c b/libc/wqueue/work_cancel.c index 8fe330ef0a1..31ccbf68d33 100644 --- a/libc/wqueue/work_cancel.c +++ b/libc/wqueue/work_cancel.c @@ -50,22 +50,6 @@ #if defined(CONFIG_LIB_USRWORK) && !defined(__KERNEL__) -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ diff --git a/libc/wqueue/work_queue.c b/libc/wqueue/work_queue.c index ba9e13c97e5..fbf166a0e49 100644 --- a/libc/wqueue/work_queue.c +++ b/libc/wqueue/work_queue.c @@ -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 * * 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) diff --git a/sched/wqueue/kwork_queue.c b/sched/wqueue/kwork_queue.c index 0ac27a87b7a..be3fd90978d 100644 --- a/sched/wqueue/kwork_queue.c +++ b/sched/wqueue/kwork_queue.c @@ -1,7 +1,7 @@ /**************************************************************************** * 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 * * 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 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. @@ -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 * 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) @@ -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, 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 if (qid == HPWORK) {