On 2011-05-12, at 12:12 PM, Mikael wrote:
(Reply to the ML is fine)
Dear Marc,
It's happened three-four times or so over here, that the REPL stopped taking input. As for today, I know that it was preceded by a thread-terminate! to a thread with a REPL in it, as for the previous times I don't remember.
The state the app got to, was that the other ##repl/mutex-lock-out-of-line-related-related threads had this status (can send you the full threads dump if you want to):
#<thread #1 primordial> 0 ##mutex-lock-out-of-line! 1 ##repl-channel-acquire-ownership! 2 ##mutex-lock-out-of-line! 3 ##repl-channel-acquire-ownership! 4 ##main
#<thread #297 (webapp-se..............> 0 ##mutex-lock-out-of-line! 1 ##repl-channel-acquire-ownership! 2 #<procedure #280>
..
Ctrl+c didn't work any more (generally it gives access to the REPL again). Though ctrl+z took me back to the underlying OS shell.
I also tried to execute (##repl) in a new thread, though this didn't work also - the thread just stopped: #<thread #687 (http-server connection-handler-thread)> 0 ##mutex-lock-out-of-line! 1 ##repl-channel-acquire-ownership! 2 #<procedure #688> "(generated)"@1:1 (##repl)
I'm on Debian with gambit 4.5.3. via putty.
So how is it - are they safe, if so, how can I debug further how to fix this?
If they're not, would it be easy to make them that, or is there any other way I can kill a thread which is in a repl?
Thanks, Mikael
As far as I can tell it is safe to terminate a thread T in a REPL with thread-terminate! . The thread T will have locked the REPL channel owner mutex (to acquire ownership of the REPL channel), so when T is terminated it will set the mutex to the "abandoned" state, so the next thread competing for the REPL channel will lock the mutex and raise the exception "abandoned mutex" which will start a nested REPL. I think it all works out, and the tests I have done (with the latest 4.6.1) seem to confirm that.
Perhaps it would be more graceful to ignore "abandoned mutex" exceptions in this case. I'll have to think about the implications.
Marc
Afficher les réponses par date
On 2011-05-18, at 10:41 AM, Marc Feeley wrote:
As far as I can tell it is safe to terminate a thread T in a REPL with thread-terminate! . The thread T will have locked the REPL channel owner mutex (to acquire ownership of the REPL channel), so when T is terminated it will set the mutex to the "abandoned" state, so the next thread competing for the REPL channel will lock the mutex and raise the exception "abandoned mutex" which will start a nested REPL. I think it all works out, and the tests I have done (with the latest 4.6.1) seem to confirm that.
Perhaps it would be more graceful to ignore "abandoned mutex" exceptions in this case. I'll have to think about the implications.
Here's a test:
% gsi -:dar Gambit v4.6.1
(thread-start! (make-thread (lambda () (thread-sleep! 1) (+ 1 xxx))))
#<thread #2>
(begin (thread-sleep! 1) (+ 2 yyy))
------------- REPL is now in #<thread #2> ------------- *** ERROR IN #<procedure #3>, (console)@1.63 -- Unbound variable: xxx
12
12 ------------- REPL is now in #<thread #1 primordial> ------------- *** ERROR IN (console)@2.31 -- Unbound variable: yyy 1> (thread-terminate! #2) *** ERROR IN (console)@2.31 -- MUTEX was abandoned 1> ,b 0 (interaction) (console)@2:31 yyy 1>
It seems to work fine. The only mild strangeness is the "MUTEX was abandoned" message, but that is because thread #2 acquired the REPL channel mutex when (thread-terminate! #2) was ***entered*** (but not yet executed) at the REPL in thread #1. So the (thread-terminate! #2) was executed by thread #1 while thread #2 was holding the mutex. Thread #2 terminated and thread #1 tried to acquire the (abandoned) mutex for the next REPL interaction, yielding an "MUTEX was abandoned" error.
Marc