# SoftBank Robotics documentation What's new in NAOqi 2.8?

# qi::Strand and qi::Actor

A `Strand` allows one to schedule asynchronous work with the guarantee that two tasks will never be executed in parallel. This is useful to avoid data races, mutexes, and deadlocks.

An `Actor` receives messages and processes them. Basically, it’s just an object containing a `Strand` so that all asynchronous work it receives will be executed sequentially.

## Summary

Global Classes

- class qi::Actor

  Functions (class qi::Actor)

  qi::Actor::joinTasks

  qi::Actor::Actor

  qi::Actor::strand

- class qi::Strand

  Functions (class qi::Strand)

  qi::Strand::isInThisContext

  qi::Strand::Strand

  qi::Strand::join

  qi::Strand::unwrappedSchedulerFor

  qi::Strand::~Strand

  qi::Strand::defer

  qi::Strand::schedulerFor

  qi::Strand::async

## Detailed Description

### Strand Usage

A `Strand` is an execution context, just like the so-called “event loop”:

    #include <qi/strand.hpp>

    qi::Strand strand;
    auto future = strand.asyncDelay(myFunction, qi::MilliSeconds(100));

    // you can now cancel future
    future.cancel();

    // and/or wait for it
    future.wait();

A strand’s destructor will block until all work scheduled is finished or canceled. You must not schedule any work when the strand is being destroyed.

A strand accepts a parent execution context at construction, on which it relies to execute the tasks. If no execution context is provided, the global “event loop” is used. Beware that the execution context must not be destroyed before all `Strands` relying on it are destroyed.

Sometimes you may need to share an object that relies on a `Strand`. But external code cannot know this implementation detail, and you cannot prevent direct calls to your object’s methods in C++. It is therefore recommended to schedule in the `Strand` all the calls to your object’s public interface. To do so, the following code pattern is to be used in every method definition:

    MyObject::myPublicMethod(const std::string& myArg)
    {
      _strand.async([myArg]
      {
        // ... your code here
      });
    }

For example, if you have the following stack implementation:

    class UnsafeIntStack
    {
      std::vector<int> _vec;

    public:
      void push(int v) { _vec.push_back(v); }
      int pop()
      {
        if _vec.empty() throw std::exception{};
        int ret = _vec.back();
        _vec.pop_back();
        return ret;
      }
    };

You can make it thread-safe without using a mutex, with the help of a `Strand`:

    class StrandedIntStack
    {
      std::vector<int> _vec;
      qi::Strand _strand;

    public:
      qi::Future<void> push(int v)
      {
        _strand.async([this, v]{ _vec.push_back(v); });
      }

      qi::Future<int> pop()
      {
        return strand.async([this]
        {
          if _vec.empty() throw std::exception{};
          int ret = _vec.back();
          _vec.pop_back();
          return ret;
        });
      }
    };

If your object is not meant to be called directly, but instead is made to be called remotely using libqi, it may be easier to use an `Actor` rather than scheduling the calls manually.

### Actor Usage

To make a single-threaded object, you can inherit from `Actor`, which is a helper class wrapping a `Strand`. `Actors` are recognized by libqi so that all RPC calls to them will be scheduled in their `Strand`. Consequently, it is guaranteed that there will never be more than one RPC call in parallel on the object. Also, no more RPC call can be processed after the `Actor` is destroyed.

Warning

`Actors` are only recommended for stand-alone objects exposed to remote clients only. If you want several objects to share a `Strand` or if the object interacts with local code (running in the same process), you should not use `Actor`!

    #include <qi/actor.hpp>

    class MyActor : public Actor
    {
    public:
      ~MyActor()
      {
        strand()->join();
      }

      void myFunction(const std::string& str);
    };

    // works with type-erasure
    QI_REGISTER_OBJECT(MyActor, myFunction);
    // works with futures
    future.connect(qi::bind(&MyActor::myFunction, myActor, "my string"));
    // works with signals
    signal.connect(qi::bind(&MyActor::myFunction, myActor, _1));
    // works with type-erased signal/property connections
    myObject.connect("mySignal",
        boost::function<void(std::string)>(
          // you need the MetaCallType_Direct to have ordering guarantees
          qi::bind(&MyActor::myFunction, myActor, _1)), MetaCallType_Direct);
    // works with periodic tasks
    periodicTask.setCallback(qi::bind(&MyActor::myFunction, myActor, _1));
    // works with async calls
    qi::asyncDelay(qi::bind(&MyActor::myFunction, myActor, "my string"),
        qi::Seconds(1));

To control better the scheduling of RPC calls, it is recommended to call `strand()->join()` at the beginning of your destructor. Joining the `Strand` guarantees there is no more work scheduled on the `Actor`.

Warning

It is not possible to inherit both from `Actor` and `Trackable` because an Actor has the same behavior as Trackable.

Warning

If you call directly an object inheriting from qi::Actor, the call is not scheduled and therefore may be performed concurrently to other calls! Joining the `Strand` does not protect from performing direct calls!

    // *NOT* single threaded
    myActor.myFunction("my string");

When connecting a callback of your object to a signal, do not use `boost::bind` or a lambda. For example, this code does not provide single-threading guarantees:

    // *NOT* single threaded
    future.connect(boost::bind(&MyActor::myFunction, myActor, "my string"));

Same thing when scheduling directly on the main eventloop.

    // *NOT* single threaded
    qi::getEventLoop()->async(boost::bind(&MyActor::myFunction, myActor,
        "my string"));

To have your calls scheduled on the strand, use `qi::bind` or explicitly strand your callback by using `qi::Actor::stranded`.

## Reference

### qi::Strand Class Reference

#### Introduction

`More...`

    #include <qi/strand.hpp>

- Inherits: `noncopyable`, `qi::ExecutionContext`

#### Public Functions

``Strand``()
``Strand``(qi::ExecutionContext& executionContext)
``~Strand``()
void ``join``()
OptionalErrorMessage ``join``(std::nothrow_t)
qi::Future<void> ``async``(const boost::function<void()>& cb, qi::SteadyClockTimePoint tp)
qi::Future<void> ``async``(const boost::function<void()>& cb, qi::Duration delay)
bool ``isInThisContext``() const
template<typename F>
auto ``schedulerFor``(F&& func, boost::function<void()> onFail, ExecutionOptions options)
template<typename F>
auto ``unwrappedSchedulerFor``(F&& func, boost::function<void()> onFail, ExecutionOptions options)
Future<void> ``defer``(const boost::function<void()>& cb, MicroSeconds delay)

#### Types

typedef boost::optional< std::string > OptionalErrorMessage

#### Detailed Description

Class that schedules tasks sequentially

A strand allows one to schedule work on an eventloop with the guaranty that two callback will never be called concurrently.

Methods are thread-safe except for destructor which must never be called concurrently.

#### Function Documentation

`qi::Strand::``Strand`()

  Construct a strand that will schedule work on the default event loop.

`qi::Strand::``Strand`(qi::ExecutionContext& executionContext)

  Construct a strand that will schedule work on executionContext.

`qi::Strand::``~Strand`()

  Call detroy()

void `qi::Strand::``join`()

  Joins the strand.

  This will wait for currently running tasks to finish and will drop all tasks scheduled from the moment of the call on. A strand can’t be reused after it has been join()ed.

  It is safe to call this method concurrently with other methods. All the returned futures will be set to error. : Under extreme circumstances such as system memory exhaustion, this method could still throw a std::bad_alloc exception, thus causing a call to std::terminate because of the noexcept specifier. This behavior is considered acceptable.

OptionalErrorMessage `qi::Strand::``join`(std::nothrow_t)

  Joins the strand.

  DeprecatedUse join() which is currently noexcept.

  This version catches any exception and returns its message. This version must be preferred in destructors to prevent abort.

  If there is no exception, an empty error message is returned.

  Example: Preventing a destructor to throw exceptions because of join. ~MyActor(){ if(constautoerror=_strand.join(std::nothrow)){ qiLogWarning()<<”Errorwhilejoiningthestrand.Detail:”<<*error; } }

qi::Future<void> `qi::Strand::``async`(const boost::function<void()>& cb, qi::SteadyClockTimePoint tp)

  call a callback asynchronously to be executed on tp Deprecatedsince 2.5

qi::Future<void> `qi::Strand::``async`(const boost::function<void()>& cb, qi::Duration delay)

  call a callback asynchronously to be executed in delay Deprecatedsince 2.5

bool `qi::Strand::``isInThisContext`()`const`

  Brief:

  Returns: | true if current code is running in this strand, false otherwise. If the strand is dying (destroy() has been called, returns false)

template<typename F>
auto `qi::Strand::``schedulerFor`(F&& func, boost::function<void()> onFail = {}, ExecutionOptions options = defaultExecutionOptions()

template<typename F>
auto `qi::Strand::``unwrappedSchedulerFor`(F&& func, boost::function<void()> onFail = {}, ExecutionOptions options = defaultExecutionOptions()

  Returns a function which, when called, defers a call to the original function to the strand, but with the return value unwrapped if possible.

Future<void> `qi::Strand::``defer`(const boost::function<void()>& cb, MicroSeconds delay = MicroSeconds::zero()

  Brief:

  Parameters: | cb – The function to execute. delay – Duration that defer will wait (without blocking the caller) before queuing the function for execution. If zero (the default value), the function will be queued immediately.
  Returns: | A future that is set once the function argument is executed

  Defers a function for execution in the strand thus without allowing the strand to call it from inside this function. It implies that this function always returns immediately.

### qi::Actor Class Reference

#### Introduction

`More...`

    #include <qi/actor.hpp>

- Inherited by: `qi::SignalSpy`

#### Public Functions

````()
````()
``Actor``(qi::ExecutionContext& ec)
````()
qi::Strand* ``strand``() const
template<class... Args>
````()
template<class... Args>
````()
template<class... Args>
````()
template<class... Args>
````()
template<class... Args>
````()
void ``joinTasks``()

#### Detailed Description

Class that represents an actor.

Inherit from this class if you want your class to be an actor (as in the actor model). This means that your class will receive “messages” and not be called. In other words, there will never be to calls to your object in parallel, they will be queued.

#### Function Documentation

`()`

`()`

`qi::Actor::``Actor`(qi::ExecutionContext& ec)

`()`

qi::Strand* `qi::Actor::``strand`()`const`

`()`

`()`

`()`

`()`

`()`

void `qi::Actor::``joinTasks`()

Glossary Site map Index Support Contact Legal Notices