This is in the context of the Microsoft C++ Concurrency API.
There's a class called agent
(under Concurrency
namespace), and it's basically a state machine you derive and implement pure virtual agent::run
.
Now, it is your responsibility to call agent::start
, which will put it in a runnable state. You then call agent::wait
*, or any of its variants, to actually execute the agent::run
method.
But why do we have to call agent::done
within the body? I mean, the obvious answer is that agent::wait
* will wait until done is signaled or the timeout has elapsed, but...
What were the designers intending? Why not have the agent enter the done state when agent::run
returns? That's what I want to know. Why do I have the option to not call done
? The wait methods throw exceptions if the timeout has elapsed.
About the only reason I can see is that it would let you state you are done()
, then do more work (say, cleanup) that you don't want your consumer to have to wait on.
Now, they could have done this:
private: void agent::do_run() {
run();
if (status() != agent_done)
done();
}
then have their framework call do_run()
instead of run()
directly (or the equivalent).
However, you'll note that you yourself can do this.
class myagent: public agent {
protected:
virtual void run() final override { /* see do_run above, except call do_run in it */ }
virtual void do_run() = 0;
};
and poof, if your do_run()
fails to call done()
, the wrapping function does it for you. If this second virtual function overhead is too high for you:
template<typename T>
class myagent: public agent {
private:
void call_do_run()
{
static_cast<T*>(this)->do_run();
}
protected:
virtual void run() final override { /* see do_run above, but call_do_run() */ }
};
the CRTP that lets you do compile-time dispatch. Use:
class foo: public myagent<foo>
{
public:
void do_run() { /* code */ }
};
... /shrug