Subject: Re: An ode to Erlang
From: (Rob Warnock)
Date: Wed, 27 Apr 2005 03:51:38 -0500
Newsgroups: comp.lang.lisp
Message-ID: <>
Helmut Eller  <> wrote:
| (Christopher C. Stacy) writes:
| > Which Lisp programs are you reporting on,
| > that you had all these bugs?
| Here's an example:
| This is SBCL's reader.  The code is almost portable CL.  And it has a
| threading bug.  Can you spot it?  The problem is the global
| *read-buffer*, a string that's used to implement various stuff
| efficiently.  But there's no code at all to synchronize concurrent
| access/modifications to the buffer.  If two unrelated threads call
| READ at the same time, they will use the same buffer and can possibly
| interfere with each other.

Interesting. The corresponding CMUCL file contains this macro:

    ;;; Recursive reader functions use with-read-buffer to allocate a
    ;;; fresh buffer.  We currently allocate a fresh buffer only for the
    ;;; exported functions READ, READ-PRESERVING-WHITESPACE,
    ;;; READ-FROM-STRING, and READ-DELIMITED-LIST.  Some internal
    ;;; READ-STRING avoid the overhead for the allocation and clobber the
    ;;; current read-buffer.  

    (defmacro with-read-buffer (() &body body)
      "Bind *read-buffer* to a fresh buffer and execute Body."
      `(let* ((*read-buffer* (allocate-read-buffer))
	      (*read-buffer-length* (length *read-buffer*))
	      (*ouch-ptr* 0)
	      (*inch-ptr* 0))
	(unwind-protect (progn ,@body)
	  (free-read-buffer *read-buffer*))))

Note that CMUCL's [and one would hope, SBCL's] MP package keeps bound
specials per-thread, thus the LET* means that each thread gets their own


Rob Warnock			<>
627 26th Avenue			<URL:>
San Mateo, CA 94403		(650)572-2607