template <typename V = void, typename E = void>

class bridge

Defined at line 136 of file ../../sdk/lib/fit-promise/include/lib/fpromise/bridge.h

A bridge is a building block for asynchronous control flow that is formed

by the association of two distinct participants: a completer and a consumer.

- The completer is responsible for reporting completion of an asynchronous

task and providing its result. See |completer| and |fpromise::completer|.

- The consumer is responsible for consuming the result of the asynchronous

task. See |consumer| and |fpromise::consumer|.

This class is often used for binding a |fpromise::promise| to a callback,

facilitating interoperation of promises with functions that asynchronously

report their result via a callback function. It can also be used more

generally anytime it is necessary to decouple completion of an asynchronous

task from consumption of its result (possibly on different threads).

The completer and consumer each possesses a unique capability that can

be exercised at most once during their association: the asynchronous

task represented by a bridge can be completed at most once and its

result can be consumed at most once. This property is enforced by

a single-ownership model for completers and consumers.

The completion capability has a single owner represented by |fpromise::completer|.

Its owner may exercise the capability to complete the task (provide its result),

it may transfer the capability by moving it to another completer instance,

or it may cause the asynchronous task to be "abandoned" by discarding the

capability, implying that the task can never produce a result. When this

occurs, the associated consumer's |fpromise::consumer::was_abandoned()| method

will return true and the consumer will not obtain any result from the task.

See |fpromise::consumer::promise()| and |fpromise::consumer::promise_or()| for

details on how abandonment of the task can be handled by the consumer.

The consumption capability has a single owner represented by |fpromise::consumer|.

Its owner may exercise the capability to consume the task's result (as a

promise), it may transfer the capability by moving it to another consumer

instance, or it may cause the asynchronous task to be "canceled" by

discarding the capability, implying that the task's result can never be

consumed. When this occurs, the associated completer's

|fpromise::completer::was_canceled()| method will return true and the task's

eventual result (if any) will be silently discarded.

DECOUPLING

See |fpromise::schedule_for_consumer| for a helper which uses a bridge to

decouple completion and consumption of a task's result so they can be

performed on different executors.

SYNOPSIS

|V| is the type of value produced when the task completes successfully.

Use |std::tuple

<Args

...>| if the task produces multiple values, such as

when you intend to bind the task's completer to a callback with multiple

arguments using |fpromise::completer::bind_tuple()|.

Defaults to |void|.

|E| is the type of error produced when the task completes with an error.

Defaults to |void|.

EXAMPLE

Imagine a File I/O library offers a callback-based asynchronous reading

function. We suppose that the read handling code will invoke the

callback upon completion. The library's API might look a bit like this:

using read_callback = fit::function

<void

(size_t bytes_read)>;

void read_async(size_t num_bytes, uint8_t* buffer, read_callback cb);

Here's how we can adapt the library's "read_async" function to a

|fpromise::promise| by binding its callback to a bridge:

fpromise::promise

<size

_t> promise_read(uint8_t* buffer, size_t num_bytes) {

fpromise::bridge

<size

_t> bridge;

read_async(num_bytes, buffer, bridge.completer.bind());

return bridge.consumer.promise_or(::fpromise::error());

}

Finally we can chain additional asynchronous tasks to be performed upon

completion of the promised read:

uint8_t buffer[4096];

void my_program(fpromise::executor* executor) {

auto promise = promise_read(buffer, sizeof(buffer))

.and_then([] (const size_t

&

bytes_read) {

// consume contents of buffer

})

.or_else() {

// handle error case

});

executor->schedule_task(std::move(promise));

}

Similarly, suppose the File I/O library offers a callback-based asynchronous

writing function that can return a variety of errors encoded as negative

sizes. Here's how we might decode those errors uniformly into |fpromise::result|

allowing them to be handled using combinators such as |or_else|.

using write_callback = fit::function

<void

(size_t bytes_written, int error)>;

void write_async(size_t num_bytes, uint8_t* buffer, write_callback cb);

fpromise::promise

<size

_t, int> promise_write(uint8_t* buffer, size_t num_bytes) {

fpromise::bridge

<size

_t, int> bridge;

write_async(num_bytes, buffer,

[completer = std::move(bridge.completer)](size_t bytes_written, int error) {

if (bytes_written == 0) {

completer.complete_error(error);

return;

}

completer.complete_ok(bytes_written);

});

return bridge.consumer.promise_or(::fpromise::error(ERR_ABANDONED));

}

uint8_t buffer[4096];

void my_program(fpromise::executor* executor) {

auto promise = promise_write(buffer, sizeof(buffer))

.and_then([] (const size_t

&

bytes_written) {

// consume contents of buffer

})

.or_else(const int

&

error) {

// handle error case

});

executor->schedule_task(std::move(promise));

}

See documentation of |fpromise::promise| for more information.

Public Members

completer_type completer
consumer_type consumer

Public Methods

void bridge<V, E> ()

Creates a bridge representing a new asynchronous task formed by the

association of a completer and consumer.

Defined at line 146 of file ../../sdk/lib/fit-promise/include/lib/fpromise/bridge.h

void bridge<V, E> (bridge<V, E> && other)

Defined at line 150 of file ../../sdk/lib/fit-promise/include/lib/fpromise/bridge.h

void bridge<V, E> (const bridge<V, E> & other)

Defined at line 151 of file ../../sdk/lib/fit-promise/include/lib/fpromise/bridge.h

void ~bridge<V, E> ()

Defined at line 152 of file ../../sdk/lib/fit-promise/include/lib/fpromise/bridge.h

bridge<V, E> & operator= (bridge<V, E> && other)

Defined at line 154 of file ../../sdk/lib/fit-promise/include/lib/fpromise/bridge.h

bridge<V, E> & operator= (const bridge<V, E> & other)

Defined at line 155 of file ../../sdk/lib/fit-promise/include/lib/fpromise/bridge.h