Question

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.

Was it helpful?

Solution

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top