On Tue, Jul 03, 2007 at 08:34:04PM +0300, Nikodemus Siivola wrote:
> Osei Poku wrote:
> >I have a queue of database connections and multiple threads (about a
> >1000) want access to these connections. A combination of a mutex and
> >a wait-queue guards the queue by making each thread do a
> >CONDITION-WAIT for access to the queue. I have a function to
> >CONDITION-NOTIFY whenever, a db connection is returned to the queue
> >and this function is called by each thread that does not need the db
> >connection anymore. However some threads are waking up to an empty
> >queue and thus obtaining nil database connections. The details are
> >(defun acquire-connection-from-queue ()
> > "Retrieves a connection from the connection queue"
> > (with-mutex (*cq-lock*)
> > (condition-wait *cq-cond-var* *cq-lock*)
> > (pop *connection-queue*)))
> Here's the bug: CONDITION-WAIT can and will get spurious wakeups.
> The only guarantees are that after you return you will be holding the
> lock, and that wakeups will not be lost.
> Correct way to write this is:
> (with-mutex (*cq-lock*)
> (condition-wait *cq-cond-var* *cq-lock*)
> (let ((conn (pop *connection-queue*)))
> (when conn
> (return conn)))))
> ...and yes, I agree, the documentation doesn't make this as clear
> as it should.
OK. Thanks for the clarification. I realize now that I did not
interpret the documentation correctly. The documentation is actually
clear on this issue as pointed out by other replies in this thread. I
ended doing this something like this eventually. It is nice to
understand the reason behind this though.
> -- Nikodemus
PhD Student, ECE
Carnegie Mellon University