Hi! We have been having a strange annoyance - probably very simple to solve - for quite some while, and I wanted to address it here so that we and anyone running into it might get around it.
What we do is to run a procedure that runs (load) multiple times in a sequence, where the (load):s are such that they output multiple warnings about unresolved symbols during the process. I'm well aware that unresolved symbols are not acceptable in final code, but, during development, there may be good reasons to prioritize other things than fixing symbol usage in code that's not used in the present moment anyhow. As you know, the general pattern for unresolved symbol warnings output by (load) is
*** WARNING -- Variable "some-module-name#some-function-name" used in module "some-object-file.o1" is undefined
The problem is that when we execute the procedure from another thread than the primordial, quite each of its warning output operations block (i.e. is blocked / freezes / waits), and gets output to the console first after that one makes an evaluation in the REPL. Making a thread-sleep! or evaluating zero is sufficient. After the evaluation, the procedure resumes until it outputs another line, and then another evaluation needs to be made to make it resume again, etc.
How do we make (load) never block, undepending of in what thread it is executed?
Example code below.
Thanks Mikael
-
Set up test environment
echo "(define (test) (unknown-symbol-a) (unknown-symbol-b) (unknown-symbol-c))" > a.scm echo "(define (test) (unknown-symbol-d) (unknown-symbol-e) (unknown-symbol-f))" > b.scm echo "(define (test) (unknown-symbol-g) (unknown-symbol-h) (unknown-symbol-i))" > c.scm
gsc (compile-file "a.scm") (compile-file "b.scm") (compile-file "c.scm") ,q
Expected behaviour, load:s don't block:
gsc (load "a") (load "b") (load "c") ,q
Output is:
(load "a") (load "b") (load "c")
"/home/mikael/a"
*** WARNING -- Variable "unknown-symbol-d" used in module "b.o1" is
undefined *** WARNING -- Variable "unknown-symbol-e" used in module "b.o1" is undefined *** WARNING -- Variable "unknown-symbol-f" used in module "b.o1" is undefined "/home/mikael/b.o1"
*** WARNING -- Variable "unknown-symbol-g" used in module "c.o1" is
undefined *** WARNING -- Variable "unknown-symbol-h" used in module "c.o1" is undefined *** WARNING -- Variable "unknown-symbol-i" used in module "c.o1" is undefined "/home/mikael/c.o1"
Unexpected behaviour, load:s block:
gsc (thread-start! (make-thread (lambda () (load "a") (load "b") (load "c"))))
Output is:
#<thread #2>
(thread-sleep! 5) ------------- REPL is now in #<thread #2> ------------- *** WARNING -- Variable "unknown-symbol-d" used in module "b.o1" is undefined *** WARNING -- Variable "unknown-symbol-e" used in module "b.o1" is undefined *** WARNING -- Variable "unknown-symbol-f" used in module "b.o1" is undefined *** WARNING -- Variable "unknown-symbol-g" used in module "c.o1" is undefined *** WARNING -- Variable "unknown-symbol-h" used in module "c.o1" is undefined *** WARNING -- Variable "unknown-symbol-i" used in module "c.o1" is undefined ------------- REPL is now in #<thread #1 primordial> -------------
Alternatively:
#<thread #2>
0
0 ------------- REPL is now in #<thread #2> ------------- *** WARNING -- Variable "unknown-symbol-a" used in module "a.o1" is undefined ------------- REPL is now in #<thread #1 primordial> -------------
0
0 ------------- REPL is now in #<thread #2> ------------- *** WARNING -- Variable "unknown-symbol-b" used in module "a.o1" is undefined ------------- REPL is now in #<thread #1 primordial> -------------
0
0 ------------- REPL is now in #<thread #2> ------------- *** WARNING -- Variable "unknown-symbol-c" used in module "a.o1" is undefined ------------- REPL is now in #<thread #1 primordial> -------------
0
0 ------------- REPL is now in #<thread #2> ------------- *** WARNING -- Variable "unknown-symbol-d" used in module "b.o1" is undefined ------------- REPL is now in #<thread #1 primordial> -------------
0
0 ------------- REPL is now in #<thread #2> ------------- *** WARNING -- Variable "unknown-symbol-e" used in module "b.o1" is undefined ------------- REPL is now in #<thread #1 primordial> -------------
0
0 ------------- REPL is now in #<thread #2> ------------- *** WARNING -- Variable "unknown-symbol-f" used in module "b.o1" is undefined ------------- REPL is now in #<thread #1 primordial> -------------
0
0 ------------- REPL is now in #<thread #2> ------------- *** WARNING -- Variable "unknown-symbol-g" used in module "c.o1" is undefined ------------- REPL is now in #<thread #1 primordial> -------------
0
0 ------------- REPL is now in #<thread #2> ------------- *** WARNING -- Variable "unknown-symbol-h" used in module "c.o1" is undefined ------------- REPL is now in #<thread #1 primordial> -------------
0
0 ------------- REPL is now in #<thread #2> ------------- *** WARNING -- Variable "unknown-symbol-i" used in module "c.o1" is undefined ------------- REPL is now in #<thread #1 primordial> -------------
0
0
0
0
Afficher les réponses par date
On 23-Sep-08, at 2:29 AM, Mikael More wrote:
How do we make (load) never block, undepending of in what thread it is executed?
The problem is that currently the console is being multiplexed between all the threads interacting with the user. There are 2 solutions:
1) Use an IDE (soon to be available) which will give each thread its own independent REPL, so the threads will not race to use the common console.
2) The internal implementation of "load" supports a "quiet?" parameter. So you can use the following definition of "load-quietly" which is just like "load" but does not display the warnings.
(define (load-quietly path) (if (not (string? path)) (error "string expected") (##load path (lambda (script-line script-path) #f) #t #t #t)))
(set! load load-quietly) ;; optional