Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!rutgers!ucsd!tut.cis.ohio-state.edu!gem.mps.ohio-state.edu!apple!well!nagle From: nagle@well.UUCP (John Nagle) Newsgroups: comp.lang.c++ Subject: Re: Combining event driven and object orient programming Message-ID: <13929@well.UUCP> Date: 4 Oct 89 06:48:55 GMT References: <13928@well.UUCP> Reply-To: nagle@well.UUCP (John Nagle) Distribution: all Lines: 49 What you really need is serious concurrency support. Here's why. With a language like C++, there is the potential to have a lot of bookkeeping taken care of automatically as objects are created and then destroyed as scopes are exited. Unfortunately, in event-driven single-thread programs, you can't do this, because essentially all context associated with where control is in the program (basically, the information on the stack) is lost every time you go back to the top of the event loop. In principle, if one has cheap multitasking (called, variously, "threads", "lightweight processes", or "weak fork"), an elegant solution is for events which will require processing beyond the current event to fork off a new task to handle them, requesting that related events be forwarded to that task. The task can have lots of context, and lots of "auto" storage-class (in the C sense) objects. For example, if you have a program with lots of menus and windows, each time the user makes a menu selection that causes a window to be opened, it should result in a task being forked off to handle that window. User-generated events in that window are then sent to the task associated with that window. It should be possible for this process to be repeated recursively as necessary. Each of these little tasks looks a lot like an old-fashioned sequential program. Rather than always going back to the event loop, these tasks do something and wait for the user to respond. If the user wants to do something else, a higher level task will fork off a task to handle it. It helps if Ada-like exception handling is available. This provides a clean way to bail out with proper unwinding when necessary. The combination of multitasking, destructors, and exception processing makes cleanup almost painless. Also essential is automatic multitasking interlocks, or "monitors". The idea is that if you want to access data shared with another task, you must call an access function of a class that is declared as allowing object sharing across task boundaries. When one task has control inside a function of such a class, other tasks are blocked if they call a function of the class. This protects shared data automatically. When you think about this, it makes sense. An event loop is really a dumb sort of CPU dispatcher, after all. With a smarter dispatcher, we could have much more elegant programs. Now how do we get multithread C++? John Nagle