The message dispatching thread loop

The subclass thread's run() method would typically consist of a loop that looks like this:

#include <x/stopexception.H>

void myClass::run()
{
    try {
        while (1)
        {
            msgqueue->pop()->dispatch();
        }
    } catch (const x::stopexception &)
    {
    }
}

In this example x::eventqueuemsgdispatcherObj implements an event file descriptor-based message queue. The msgqueue class member is the event queue. x::run() starts a thread that runs the class's run() method that starts reading messages from the event queue, and invoking their dispatch() method.

sendevent constructs x::dispatchablemsgObjs and invokes event(), which gets implemented in x::eventqueuemsgdispatcherObj. event() puts the messages into the queue, which run() drains.

x::dispatchablemsgObj instances contain messages, and the this that was passed to sendevent, that's typically the same object whose method is draining the message queue. Its dispatch() uses the stored this to invoke the overloaded dispatch methods.

The overloaded dispatch methods are private methods, in this typical example, and may only be invoked by calling the public methods that queue up the messages to the thread. Subsequently, they get only invoked by the object's run() thread. As demonstrated by the example, x::dispatchablemsgObj needs a friend declaration so it can invoke the private method.

The message classes are also private inner classes, and can only be instanted by calling the public methods that queue up the messages to the class instance.

For convenience, x::msgdispatcherObj defines a stop() method that queues up a message that, when dispatch()ed, throws a x::stopexception, as a means of terminating the message-dispatching thread. As shown in the previous example, this exception should be caught.

Summary of the message dispatching-based thread design pattern.