Last updated at 6:47 am UTC on 29 May 2007
An event-loop architecture uses a single thread with an infinite loop like the following:
[ true ] whileTrue: [
event := "next event".
self processEvent: event ]
The difficulty of this architecture is that the processing of an event is not allowed to pause and wait for something to happen; if it does, then the entire event loop freezes and thus the program becomes unresponsive. Instead, whenever one would program a wait in a multi-threaded program, one should queue an event in an event-loop-based program. An example of such a method is addDeferredUIMessage: from Morphic. Alternatively, one can use Morphic's Stepping mechanism.
There are significant advantages to this architecture, however.
Primarily, the problem of locking disappears. Every event is processed with the program in a sane state.
Second, executions become repeatable. The program will behave the same way on other people's machines as it did when it was tested.
Third, tests for unusual sequences become easier to code. One can simply create a sequence of events that simulate the bizarre behavior. One does not need to trick the scheduler into running threads in a particular strange sequence.
Fourth, the debugging tools are simplified. With this architecture, a single-threaded debugger works fine.
Finally, by avoiding all waits, it lays the groundwork for implementing exceptional conditions such as "abort" buttons and "window closing" events; such conditions are difficult to support if the program might be in any of the wait. Looked at the other way, if a program needs to support "abort" or "window close" kind of events, then it needs to program all waits, anyway, so that the waits can be aborted. This additional complexity seems likely to be just as large as the complexity of avoiding waits to begin with.
An alternative architecture is Preemptive Threads with Shared Memory.
Tweak uses an event-based architecture but allows multiple threads to run. It is unclear exactly when event handlers are allowed to be suspended, but it has been claimed that both (1) it is impossible for a handler to freeze the UI, and (2) handlers do not get preempted. Clarification is welcome.