Index
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:
One execution thread for each instance of the class. Multiple execution threads require a separate instance of the class.
The class exports public methods that take their parameters and save them in an internal message objects. Other threads invoke these public methods.
The class maintains an internal thread-safe message queue. Each public method creates a message object, puts its parameters into the message object, and adds it to the message queue.
The execution thread runs a loop that takes messages off the
internal queue. Each message invokes a private class method.
The original
parameters that were passed to the public class method get forwarded
to the private class method, which now gets invoked by
x::threadmsgdispatcherObj
's execution class.
The execution thread stops by throwing an exception in one of the private methods. The exception breaks out of the execution thread's message dispatching loop and terminates the execution thread. Alternatively, the execution thread can check a private flag that gets set to terminate the execution thread, and terminate its message dispatching loop based on that.
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
#include
d 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.
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.