I discovered another terrible bit of code I had written, where my naive expectations of what cmucl would do and the disappointing reality of cmucl's behavior conspired to destroy any semblance of interactivity in Echo.
I was using ext:run-program to run a unix executable. And I gave it a :wait argument of T because, well, I really wanted the program to finish running before I returned a value from my function. And it worked great, except that it completely blocked all lisp threads from running until the other program finished. I sigh.
The problem is in ext:process-wait, which is what ext:run-program uses when :wait is T:
(defun process-wait (proc &optional check-for-stopped) "Wait for PROC to quit running for some reason. Returns PROC." (declare (type process proc)) (loop (case (process-status proc) (:running) (:stopped (when check-for-stopped (return))) (t (when (zerop (car (process-cookie proc))) (return)))) (system:serve-all-events 1)) proc)
(Actually, it seems to me that the call to system:serve-all-events should cause other threads to run, but experimentally I have verified that they don't.)
I basically replaced ext:process-wait with the following code, which makes everything work better:
(mp:process-wait "waiting for exec" #'(lambda () (let ((status (process-status process))) (and (not (eq status :running)) (not (eq status :signaled))))))
Well, that can't help but improve responsiveness of a server that runs external programs constantly, can it? As long as it is correct and safe. Please let it be correct and safe.
cmucl's behavior here probably doesn't count as a bug, but it sure isn't the best one could hope for. I think it was Tim Moore that once said something about trying to decide whether it would be better to rewrite cmucl to be as non-blocking as possible, or to add native thread support. I suppose the right thing to do is... both.Posted by jjwiseman at February 10, 2002 12:50 AM