From 2d93dc5eb5e9a1c93b2163af83f427f83ae2095e Mon Sep 17 00:00:00 2001 From: Nikodemus Siivola Date: Mon, 8 Nov 2010 10:00:53 +0000 Subject: [PATCH] 1.0.44.3: better docstring for CONDITION-WAIT Mention the fact that it might get spurious wakeups. --- src/code/target-thread.lisp | 31 ++++++++++++++++++++++++++----- version.lisp-expr | 2 +- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/code/target-thread.lisp b/src/code/target-thread.lisp index 0b129d1..25a6c17 100644 --- a/src/code/target-thread.lisp +++ b/src/code/target-thread.lisp @@ -559,11 +559,32 @@ IF-NOT-OWNER is :FORCE)." (defun condition-wait (queue mutex) #!+sb-doc - "Atomically release MUTEX and enqueue ourselves on QUEUE. Another -thread may subsequently notify us using CONDITION-NOTIFY, at which -time we reacquire MUTEX and return to the caller. - -Note that if CONDITION-WAIT unwinds (due to eg. a timeout) instead of + "Atomically release MUTEX and enqueue ourselves on QUEUE. Another thread may +subsequently notify us using CONDITION-NOTIFY, at which time we reacquire +MUTEX and return to the caller. + +Important: CONDITION-WAIT may return without CONDITION-NOTIFY having occurred. +The correct way to write code that uses CONDITION-WAIT is to loop around the +call, checking the the associated data: + + (defvar *data* nil) + (defvar *queue* (make-waitqueue)) + (defvar *lock* (make-mutex)) + + ;; Consumer + (defun pop-data () + (with-mutex (*lock*) + (loop until *data* + do (condition-wait *queue* *lock*)) + (pop *data*))) + + ;; Producer + (defun push-data (data) + (with-mutex (*lock*) + (push data *data*) + (condition-notify *queue*))) + +Also note that if CONDITION-WAIT unwinds (due to eg. a timeout) instead of returning normally, it may do so without holding the mutex." #!-sb-thread (declare (ignore queue)) (assert mutex) diff --git a/version.lisp-expr b/version.lisp-expr index 1fe853e..fd205fc 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"1.0.44.2" +"1.0.44.3" -- 1.7.10.4