Luke Gorrie luke@bluetail.com writes:
[...]
Very simple, and it has been very good during debugging that illegal transitions are nicely detected.
The trouble is that it didn't cope with Lisp initiating "asynchronous" transitions, as does happen in real life. In general, we end up either disallowing these things, or introducing protocol-level race conditions to permit them with extra transitions.
Yes, that's a good observation. Also, disallowing asynchronous things has not worked very well. People happily use the *inferior-lisp* buffer and multi-threading, even if we say it's not supported :-)
[...]
One trend I see is that states increasingly have a lot of transitions in common, e.g. anything could transition into the debugger.
Yeah, I noticed this too.
We may end up with so many common transitions that it's easier to say which transitions _aren't_ allowed in each state -- in which case maybe we end up rewriting the state machine as a single function.
Interesting point of view. The first question that arises is "what transition should be disabled?" We probably shouldn't allow evaluation requests when Lisp is already busy. It seems to be preferable to do this check on the Emacs side, because it isn't cool if slime-space makes a RPC just to discover that Lisp is busy. OTOH, this is difficult with asynchronous events, because the automaton on the Emacs side may be out of sync with Lisp's actual state, e.g., Lisp may execute an endless loop in an fd-handler, but Emacs thinks Lisp is idle. It is not easy to tell Emacs everything what Lisp is doing.
The other thing is that there are fundamental race conditions, because in reality both Emacs and Lisp can initiate transitions, potentially at the same time. We need to cook up a scheme for resolving these races in a sane way.
Good point. I think, it will be easier resolve these race conditions on the Lisp side, because it is easier to access the actual state.
One idea is that we include a "stack descriptor" in each message. A stack descriptor could be something like (idle eval debugging) or a string with the initial letters of the states "IED". To detect race condition we compare the stack descriptor in the message with the local stack. We know there's a race condition (or some other problem) if the descriptors don't match. The problem can than be handled depending on the current state and the message.
Another idea that might be useful: we could use signal driven I/O on the on the socket, so that Lisp responds to our messages even when it is busy. This might also be useful if Lisp is on a different host. Hemlock uses oob data in this situation, but alas, Emacs doesn't support that.
Helmut.