[reSIProcate] DUM v. 2 proposal (early draft)
Hi again,
Alas, there were no takers (except for a few observers, thanks) for the DUM v. 2
discussion. So I went ahead and thought about it by (mostly) myself.
As always, I try to be sensitive to alarming the community with hairy template
tricks, so I limited myself to a few simple templates and some STL.
My goals:
1. easy to use
2. timing safe
3. multi-thread enabled
4. type safe
5. open issues
Easy to use:
1. collapse the usage/application instance and the handle/handled
The user defines application usage ('usage' in a loose sense) as publically
inheriting from the relevant DUM usage base. Vanilla polymorphism -- other than
that, the class is unconstrained. For example:
class MyClientRegister : public DUM::ClientRegister // other parents desired
{
public:
// any constructor desired
MyClientRegister(...);
// any state desired
// any additional functionality desired
};
2. timing safe
The user passes their instance to DUM for managing.
DUMPtr is a template. It is a reference counting smart pointer and has a
reference to the application instance. When the DUMPtr counter goes to zero, the
usage is ended(). Eventually, the instance is deleted by DUM.
DUMPtr<MyClientRegister> reg = mDUM.manage(make_auto<new MyClientRegister(...));
The manage method is templatized; for environements that don't support method
templating, a templatized global function will work, too.
make_auto is a very simple templatized function analogous to std::make_pair. It
is purely syntactic sugar. The alternative is:
std::auto_ptr<MyClientRegister>(new MyClientRegister(...))
The registration is started by the application; ask for the message, adorn it,
and send it. Maybe provide a send() with no arguments for simplicity. Of course,
access to the instance from the application is via the DUMPtr.
3. multi-thread enabled.
When an application usage is managed, the application can specify a fifo. This
fifo is expected to have a thread consumer that calls a distinct DUM process
interface. The main DUM process interface will act as a fifo selector and
producer (that is, it determines which fifo to queue to). Only for its internal
fifo (the default fifo) will DUM::process dispatch. The other fifos expect
dispatching to occur from some other thread.
For example:
// assume the application has a thread calling DUM::dispatch with mAppFifo
// where mAppFifo is a Fifo<Message>:
DUMPtr<MyClientRegister> reg =
mDUM.manage(make_auto<new yClientRegister(...), mAppFifo);
This will require some mutexing internal to DUM, particularly in manage and
dispatch. The mutexing could be (runtime?) policy driven, but is probably not
worth avoiding?
4. type safe
Templatizing the DUMPtr returned by DUM::manage() provides type safety. The
virtual method on the usages also provide type safety; no messy casting of
application data there -- 'this' *is* the application instance.
5. open issues
Invitation and Subscription are a bit more complicated. Derek and I are kicking
around an idea where the application instance acts as collection
(DialogSet-ish), instance, and factory. More thought required here, particularly
for how to get forks wrapped in DUMPtrs (templates, he says), and how to manage
other requests within dialogs. Input sought.
Gentlepersons, start your bullhorns..
david