Chapter 22. Message dispatching-based thread design pattern

Index

Sending messages to the thread
Starting the message-dispatching execution thread
The message queue
Using the message queue
Auxiliary message queues
Stopping the execution thread
Generic stoppable interface
Using a stylesheet to generate a thread-based message dispatching framework
XML definitions
Generating doxygen documentation
GNU make macros
Using GNU make macros with automake

x::threadmsgdispatcherObj is a reference-counted object that implements a design pattern for a message-based thread class. A dedicated execution thread runs in a loop that retrieves messages from other threads, and responds to them.

This design pattern contains several elements:

Public methods comprise the public interface to the class. Public methods take their parameters and place them in a message queue. All parameters must be copyable.

It's more convenient, in most situations, to use an XSLT stylesheet that takes a compact definitions of methods and their parameters. The stylesheet generates the code that defines the public methods that takes their parameters, place the internal messages into the dispatching queue, and declares the private class methods. The end result gets conveniently #included into the class definition. The following examples demonstrate the inner workings of x::threadmsgdispatcherObj, and the mechanism that drives message dispatching.

#include <x/threadmsgdispatcher.H>
#include <x/ptr.H>
#include <x/obj.H>
#include <x/logger.H>

class myThreadObj : public x::threadmsgdispatcherObj {

    LOG_CLASS_SCOPE;

    void dispatch_statusinquiry(bool format);

    void dispatch_refresh(const std::string & name);


public:

    myThreadObj()=default;

    ~myThreadObj()=default;

    void statusinquiry(bool format);

    void refresh(const std::string &name);

    void run(x::ptr<x::obj> &threadmsgdispatcher_mcguffin)
    {
        msgqueue_auto msgqueue(this);

        threadmsgdispatcher_mcguffin=nullptr;

        while (1)
           msgqueue.event();
    }
};

LOG_CLASS_INIT(myThreadObj);

typedef x::ref<myThreadObj> myClass;

This simple class defines two messages, statusinquiry and refresh (there's also a default stop message inherited from x::threadmsgdispatcherObj), represented by two public methods.

Sending messages to the thread

    void statusinquiry(bool format)
    {
        this->sendevent(&myThreadObj::dispatch_statusinquiry,
                        this, format);
    }

    void refresh(const std::string &name)
    {
        this->sendevent(&myThreadObj::dispatch_refresh
                        this, name);
    }

The x::threadmsgdispatcherObj superclass defines the sendevent() template method. sendevent() takes the following parameters:

  • A pointer to a class method.

  • The this value. Each subclass of x::threadmsgdispatcherObj can define its own public/private methods, and use sendevent().

  • Any additional parameters get forwarded to the private class method.