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)
{