Helmut Eller <e9626484@stud3.tuwien.ac.at> wrote:
+---------------
| cstacy@news.dtpq.com (Christopher C. Stacy) writes:
| > Which Lisp programs are you reporting on,
| > that you had all these bugs?
|
| Here's an example:
|
| http://cvs.sourceforge.net/viewcvs.py/sbcl/sbcl/src/code/reader.lisp?rev=1.42&view=auto
|
| 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
;;; functions like READ-TOKEN, INTERNAL-READ-EXTENDED-TOKEN and
;;; 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
private *READ-BUFFER*, *READ-BUFFER-LENGTH*, *OUCH-PTR*, & *INCH-PTR*.
-Rob
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607