updogliu
updogliu

Reputation: 6255

Is there a way to check whether a stackful coroutine is in the context of a given strand?

Given a yield_context object y, and a strand s, is there a way to check whether y represents a coroutine in the context of s or not?

Upvotes: 1

Views: 361

Answers (1)

Tanner Sansbury
Tanner Sansbury

Reputation: 51941

Given a yield_context and strand object, it is not possible to detect if a yield_context's executor context is a specific strand. However, within the execution of a coroutine, one can detect if the current coroutine's executor context is a specific strand via invoking strand::running_in_this_thread(). It is a subtle distinction, but here is an example demonstrating its usage:

#include <cassert>
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>

int main()
{
  boost::asio::io_service io_service;
  boost::asio::io_service::strand strand1(io_service);
  boost::asio::io_service::strand strand2(io_service);
  boost::asio::io_service::strand strand3(strand1);

  boost::asio::spawn(strand1,
    [&](boost::asio::yield_context yield)
    {
      assert(strand1.running_in_this_thread());
      assert(!strand2.running_in_this_thread());
      assert(strand3.running_in_this_thread());

      // Access implementation details.
      auto strand4 = yield.handler_.dispatcher_;
      assert(strand4.running_in_this_thread());

      // No way to compare strands to one another.  Although strand1, strand3,
      // and strand4 use the same strand implementation, the strand objects
      // are neither identifiable nor comparable.
    });

  io_service.run();
}

The reason one cannot detect if a yield_context object's executor context is a specific strand object is because the strand API provides neither a way to perform identification nor comparison. In the above example, although strand1, strand3, and strand4 refer to the same strand implementation, the only way to deduce that they use the same implementation is to check each one within the execution context of one of the strands. Furthermore, even if strands were comparable, the supported API for yield_context does not expose the coroutine's executor context.

Upvotes: 4

Related Questions