Dirk Gerrits dirk@dirkgerrits.com writes:
REPL command are executed by the repl thread. For the other request, a new worker thread is created by the control thread. So, the-right-thread(s) are probably the control thread and the repl thread.
This seems strange. Has any of this changed recently? It doesn't seem to explain the behaviour I reported earlier:
No; not since June.
In my package.lisp file, I've got the following:
(eval-when (:compile-toplevel :load-toplevel :execute) (with-open-file (stream "thread-id.txt" :direction :output :if-exists :append) (print (sb-thread:current-thread-id) stream))
;; Use long-floats instead of single-floats by default. (setq *read-default-float-format* 'long-float))
When I do a ,load-system of my ASDF system from the REPL, the processing of this file generated thread-ids:
23673 23710 23710
The REPL has thread-id 23710 as well. So I guess COMPILE-OP is done in a seperate thread but LOAD-OP is done in the REPL thread? Using the *inferior-lisp* buffer's REPL reports 23706, by the way.
This says inferior-lisp /= SBCL REPL, and the SETQ was apparently executed in the REPL thread yet the binding wasn't inherited by the worker threads.
I think only the last 2 lines are created by one ,load-op. At least (load (compile-file ...)) produces only 2 lines. It would also be strange to have a thread id (23673) smaller than the id of the SBCL REPL thread (23706).
I'll try this out again soon. If the thread tree is really as you describe, and ,load-system is done in the SCBL REPL thread, then there shouldn't be a problem at all, right?
Only if you do it before the other threads are created, of course. If you do it afterwards, the value in the other threads remains unchanged.
The issue came up before but I still don't know what the proper fix is. SBCL is the only Lisp with the inherit-dynamic-variables-in-new-threads semantics.
I thought AllegroCL 7 and Corman Common Lisp (and possibly others) also behaved in this way? In any case, it seems to me that this is the reasonable thing to do with special variable bindings in a multithreaded setting.
Not sure about Corman, but in Allegro the dynamic environment in new thread is initially empty. See http://www.franz.com/support/documentation/7.0/doc/multiprocessing.htm#dynam...
Implementing non-inheriting seems to be difficult in SBCL and implementing inheriting is difficult in the other Lisps. We could probably offer something like swank:setq-default to set initial values in the worker threads. Other ideas?
I reckon the problem is a lot deeper than SBCL + SLIME, but SWANK:SETQ-DEFAULT sounds like a good workaround.
I added a new variable *default-worker-thread-bindings* instead. The intended use is something like
(push (cons '*read-default-float-format* 'long-float) *default-worker-thread-bindings*)
Only new worker threads are affected by this variable. To change the variable in the REPL you have to evaluate a setq in the REPL thread.
Helmut.