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

# qi::EventLoop

Provide an eventloop based on boost::asio.

## Summary

Global Namespaces

- namespace qi

  Classes (namespace qi)

  - class qi::EventLoop

    Functions (class qi::EventLoop)

    qi::EventLoop::setMinThreads

    qi::EventLoop::monitorEventLoop

    qi::EventLoop::EventLoop

    qi::EventLoop::setMaxThreads

    qi::EventLoop::start

    qi::EventLoop::nativeHandle

    qi::EventLoop::join

    qi::EventLoop::async

    qi::EventLoop::isInThisContext

    qi::EventLoop::setEmergencyCallback

    qi::EventLoop::stop

    qi::EventLoop::~EventLoop

    qi::EventLoop::post

  Functions (namespace qi)

  qi::getIoService

  qi::getEventLoop

  qi::startEventLoop

  qi::async

## Detailed Description

This eventloop consists of a threadpool of boost::asio threads waiting for work. You can schedule work using `async` or using the `io_service` directly (to do asynchronous operations on sockets for example). Most basic usages are described in asynchronous operations.

### Good use of a threadpool

It is often needed to schedule asynchronous work so that multiple work can be done in parallel. One way to do such a thing is to spawn a thread for the task and have the thread quit when the task is finished. It is bad practice to do such things. Spawning and exiting threads is costly in performance and must be avoided.

A threadpool starts a bunch of threads at its initialization and allows one to schedule short tasks on it, this avoids thread creations/destructions.

#### Blocking threads

It is not recommended to schedule large tasks in the threadpool (like image or sound processing) since it will block a thread and be unfair to other users. Such tasks should be scheduled on separate threads (which should of course not be created/destroyed each time there is work to do) synchronized with mutexes and condition variables.

Additionally, an asynchronous task should not lock long-held mutexes or do blocking calls. Every time a task does that, a thread of the threadpool is blocked an no more work can be scheduled on it until the task finishes.

### Threadpool Monitoring

The threadpool is constantly monitored by an external thread to check if it is full (or deadlocked). The thread schedules a “ping” every 0.5 second and waits for the “pong” for 0.5 second. If it times out, a new thread is spawned until the maximum is reached. If 20 timeouts happen in a row, the emergency callback is called (which may abort execution since a deadlock is likely to have occurred).

### Customizing the Threadpool Behavior

You can control how the threadpool behaves through environment variables.

- `QI_EVENTLOOP_THREAD_COUNT`: number of threads the eventloop should start with. By default, it will start with one thread per CPU. This is overridden by calling `qi::startEventLoop` explicitly.
- `QI_EVENTLOOP_MAX_THREADS`: maximum number of threads that the threadpool can have.
- `QI_EVENTLOOP_GRACE_PERIOD`: time in ms to wait after a failed ping, defaults to 0.
- `QI_EVENTLOOP_PING_TIMEOUT`: time in ms to wait for a ping response before considering it failed, defaults to 500.
- `QI_EVENTLOOP_MAX_TIMEOUTS`: number of timeouts before calling the emergency callback, defaults to 20.

## Reference

### qi::EventLoop Class Reference

#### Introduction

Class to handle eventloop. . `More...`

    #include <qi/eventloop.hpp>

- Inherits: `qi::ExecutionContext`

#### Public Functions

template<typename R>
Future<R> ``async``(const boost::function<R()>& callback, uint64_t usDelay)
Future<void> ``async``(const boost::function<void()>& callback, uint64_t usDelay)
Future<void> ``async``(const boost::function<void()>& callback, qi::Duration delay)
Future<void> ``async``(const boost::function<void()>& callback, qi::SteadyClockTimePoint timepoint)
``EventLoop``(std::string name, int nthreads, bool spawnOnOverload)
``EventLoop``(std::string name, int nthreads, int minThreads, int maxThreads, bool spawnOnOverload)
``~EventLoop``()
bool ``isInThisContext``() const
void ``start``(int threadCount)
void ``join``()
void ``stop``()
void ``setEmergencyCallback``(boost::function<void()> cb)
void ``setMinThreads``(unsigned int min)
void ``setMaxThreads``(unsigned int max)
void* ``nativeHandle``()
void ``post``(const boost::function<void()>& callback, uint64_t usDelay)
void ``post``(const boost::function<void()>& callback, qi::Duration delay)
void ``post``(const boost::function<void()>& callback, qi::SteadyClockTimePoint timepoint)
Future<void> ``monitorEventLoop``(EventLoop* helper, uint64_t maxUsDelay)

#### Types

typedef std::shared_ptr< EventLoopPrivate > ImplPtr

#### Detailed Description

Class to handle eventloop. .

#### Function Documentation

template<typename R>

Brief: Calls given function once after given delay in microseconds.

Parameters: | callback -- Callback to be called. usDelay -- Delay before call the callback in microsecond.
Returns: | A canceleable future.

Future<R> `qi::EventLoop::``async`(const boost::function<R()>& callback, uint64_t usDelay)

  Deprecateduse qi::async with qi::Duration

Future<void> `qi::EventLoop::``async`(const boost::function<void()>& callback, uint64_t usDelay)

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

  call a callback asynchronously to be executed in delay Deprecatedsince 2.5

Future<void> `qi::EventLoop::``async`(const boost::function<void()>& callback, qi::SteadyClockTimePoint timepoint)

  call a callback asynchronously to be executed on tp Deprecatedsince 2.5

`qi::EventLoop::``EventLoop`(std::string name = "eventloop", int nthreads = 0, bool spawnOnOverload = true)

  Brief: Creates a group of threads running event loops.

  Parameters: | name – Name of the event loop to create. nthreads – Initial number of threads. If lower or equal to 0, the event loop will use in order: the value of the environment variable QI_EVENTLOOP_THREAD_COUNT if it’s set,the value returned by std::thread::hardware_concurrency() if it’s greater than 3,the fixed value of 3.

`qi::EventLoop::``EventLoop`(std::string name, int nthreads, int minThreads, int maxThreads, bool spawnOnOverload)

`qi::EventLoop::``~EventLoop`()

  Default destructor.

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

  Brief: Checks if the current thread is one of the event loop threads.

  Returns: | true if the current thread is one of the event loop threads.

void `qi::EventLoop::``start`(int threadCount = 0)

  Brief: Starts the event loop. Does nothing if already started.

  Parameters: | threadCount – Number of threads. See the constructor for more information.

  DeprecatedEventLoop automatically starts when constructed.

void `qi::EventLoop::``join`()

  DeprecatedEventLoop automatically joins when destroyed.

void `qi::EventLoop::``stop`()

  DeprecatedEventLoop automatically stops when destroyed.

void `qi::EventLoop::``setEmergencyCallback`(boost::function<void()> cb)

  Brief: Sets callback to be called in case of a deadlock detection.

  Parameters: | cb – Callback to be called.

void `qi::EventLoop::``setMinThreads`(unsigned int min)

void `qi::EventLoop::``setMaxThreads`(unsigned int max)

  Brief: Sets the maximum number of threads in the pool.

  Parameters: | max – Maximum number of threads.

void* `qi::EventLoop::``nativeHandle`()

  Internal function.

void `qi::EventLoop::``post`(const boost::function<void()>& callback, uint64_t usDelay)

  Brief: Similar to async() but without cancelation or notification.

  Parameters: | callback – Callback to be called. usDelay – Delay before call the callback in microsecond.

void `qi::EventLoop::``post`(const boost::function<void()>& callback, qi::Duration delay)

void `qi::EventLoop::``post`(const boost::function<void()>& callback, qi::SteadyClockTimePoint timepoint)

Future<void> `qi::EventLoop::``monitorEventLoop`(EventLoop* helper, uint64_t maxUsDelay)

  Brief: Monitors event loop to detect deadlocks.

  Parameters: | helper – an other event loop used for monitoring. maxUsDelay – maximum expected delay between an async() and its execution.
  Returns: | A canceleable future. Invoke cancel() to terminate monitoring. In case an async() call does not execute in time, the future’s error will be set.

EventLoop* `qi::``getEventLoop`()

  Returns the global eventloop, created on demand on first call.

void `qi::``startEventLoop`(int nthread)

  Brief: Starts the eventloop with nthread threads. Does nothing if already started.

  Parameters: | nthread – Set the minimum number of worker threads in the pool.

`qi::``getIoService`()

template<typename R>
Future<R> `qi::``async`(boost::function<R()> callback, uint64_t usDelay)

  Deprecateduse qi::async with qi::Duration

  Deprecateduse qi::async with qi::Duration

template<typename R>
Future<R> `qi::``async`(boost::function<R()> callback, qi::Duration delay)

template<typename R>
Future<R> `qi::``async`(boost::function<R()> callback, qi::SteadyClockTimePoint timepoint)

Glossary Site map Index Support Contact Legal Notices