Index: kernel/generic/include/synch/waitq.h
===================================================================
--- kernel/generic/include/synch/waitq.h	(revision ff90f5ff632907d5ecfca130f802b91bb0091a56)
+++ kernel/generic/include/synch/waitq.h	(revision 3954961e3244230c1f7f8570256342938778edb5)
@@ -77,4 +77,5 @@
 extern void waitq_sleep_finish(waitq_t *, int, ipl_t);
 extern void waitq_wakeup(waitq_t *, wakeup_mode_t);
+extern void waitq_complete_wakeup(waitq_t *);
 extern void _waitq_wakeup_unsafe(waitq_t *, wakeup_mode_t);
 extern void waitq_interrupt_sleep(struct thread *);
Index: kernel/generic/src/synch/waitq.c
===================================================================
--- kernel/generic/src/synch/waitq.c	(revision ff90f5ff632907d5ecfca130f802b91bb0091a56)
+++ kernel/generic/src/synch/waitq.c	(revision 3954961e3244230c1f7f8570256342938778edb5)
@@ -442,4 +442,42 @@
 	irq_spinlock_unlock(&wq->lock, true);
 }
+
+/** If there is a wakeup in progress actively waits for it to complete.
+ * 
+ * The function returns once the concurrently running waitq_wakeup()
+ * exits. It returns immediately if there are no concurrent wakeups 
+ * at the time.
+ * 
+ * Example usage:
+ * @code
+ * void callback(waitq *wq)
+ * {
+ *     // Do something and notify wait_for_completion() that we're done.
+ *     waitq_wakeup(wq);
+ * }
+ * void wait_for_completion(void) 
+ * {
+ *     waitq wg;
+ *     waitq_initialize(&wq);
+ *     // Run callback() in the background, pass it wq.
+ *     do_asynchronously(callback, &wq);
+ *     // Wait for callback() to complete its work.
+ *     waitq_sleep(&wq);
+ *     // callback() completed its work, but it may still be accessing 
+ *     // wq in waitq_wakeup(). Therefore it is not yet safe to return 
+ *     // or it would clobber up our stack (where wq is stored).
+ *     waitq_complete_wakeup(&wq);
+ *     // waitq_wakeup() is complete, it is safe to free wq.
+ * }
+ * @endcode
+ * 
+ * @param wq  Pointer to a wait queue.
+ */
+void waitq_complete_wakeup(waitq_t *wq)
+{
+	irq_spinlock_lock(&wq->lock, true);
+	irq_spinlock_unlock(&wq->lock, true);
+}
+
 
 /** Internal SMP- and IRQ-unsafe version of waitq_wakeup()
