Asynchronous Utility APIs#

<amongoc/async.h> (header file)#

This header contains miscellaneous asynchronous utilities and building blocks.

Functions#

amongoc_emitter [[type(U)]] amongoc_then(
amongoc_emitter [[transfer, type(T)]] em,
amongoc_async_flags flags,
mlib_allocator alloc,
amongoc_box [[transfer, type(UserData)]] userdata,
amongoc_then_transformer [[type(User=UserData, In=T, Out=U)]] tr,
)#

Connect a continuation to an amongoc_emitter.

Parameters:
  • em[[transfer]] The emitter to be composed.

  • flags – Options for the behavior of the transformed emitter.

  • alloc – The allocator for the emitter and operation state.

  • userdata[[transfer]] Arbitrary userdata that will be forwarded to tr.

  • tr – The transformer callback. See amongoc_then_transformer for information.

Returns:

A new amongoc_emitter \(R\)

Header:

amongoc/async.h

When the emitter em resolves, its result status and value will be given to tr. The return value from tr will become the new result value of the returned emitter \(R\). The transform function tr may also modify the final status to change the result status of \(R\).

Hint

If you need to start another asynchronous operation to define the new result, use amongoc_let() instead. amongoc_then() is only for synchronous continuations.

amongoc_emitter [[type(U)]] amongoc_let(
amongoc_emitter [[transfer, type(T)]] em,
amongoc_async_flags flags,
mlib_allocator alloc,
amongoc_box [[transfer, type(UserData)]] userdata,
amongoc_let_transformer [[type(User=UserData, In=T, Out=U)]] tr,
)#

Connect a continuation that defines a new asynchronous operation to be launched immediately upon completion of the input operation.

Parameters:
  • em[[transfer]] The input emitter to be composed.

  • flags – Options for the behavior of the transformed emitter.

  • alloc – The allocator for the emitter and operation state.

  • userdata[[transfer]] Arbitrary userdata that is forwarded to tr.

  • tr – The transformer callback. See amongoc_let_transformer for more information.

Returns:

A new amongoc_emitter \(R\).

Header:

amongoc/async.h

When the input emitter em resolves, the transformer function tr will be called to obtain a new emitter \(e'\). The new emitter \(e'\) will be launched immediately, and its result will be used as the result of the composed emitter \(R\).

Use this function when the initiation of an asynchronous operation depends on the result of another asynchronous operation.

amongoc_emitter [[type(T)]] amongoc_just(
amongoc_status st,
amongoc_box [[transfer, type(T)]] value,
mlib_allocator alloc,
)#

Create an emitter that will resolve immediately with the given status and result value.

Parameters:
  • st – The result status.

  • value[[transfer]] The result value.

  • alloc – The allocator for the emitter and operation state.

Returns:

A new amongoc_emitter \(R\) whose result status will be st and result value will be value

Header:

amongoc/async.h

Note

The returned emitter here is not tied to any event loop, and it will call amongoc_handler_complete() immediately within the call to amongoc_start() invoked on its associated amongoc_operation.

Note

This operation does not support cancellation and will never encounter an error during its completion except a potential amongoc_alloc_failure(). Unless allocation fails, status st and result value will always be sent to the handler.

amongoc_emitter [[type(T)]] amongoc_then_just(
amongoc_emitter [[transfer]] em,
amongoc_async_flags flags,
amongoc_status st,
amongoc_box [[transfer, type(T)]] value,
mlib_allocator alloc,
)#

Create a continuation that replaces an emitter’s result value with the given status st and result value.

Parameters:
  • em – The input operation to be modified.

  • flags – Behavior control flags.

  • st – The new status of the operation.

  • value – The new value of the operation.

  • alloc – The allocator for the emitter and operation state.

Returns:

A new emitter \(R\) for the composed operation.

Header:

amongoc/async.h

Upon successful completion, the result value from em will be immediately destroyed and the emitter \(R\) will resolve with st and value. Upon failure (i.e. if flags specify a different behavior), then the value object will be destroyed and the error will be propagated.

amongoc_emitter [[type(nil)]] amongoc_schedule(amongoc_loop *loop)#

Create an emitter that will resolve within the given event loop as soon as possible.

Parameters:

loop – The event loop that will invoke amongoc_handler_complete() on the handler.

Returns:

An amongoc_emitter for the schedule operation. It will always emit amongoc_nil to its handler.

Allocation:

This operation uses the event loop’s allocator.

Header:

amongoc/async.h

When connected to a handler and the resulting operation is started, the handler for the operation will be enqueued with the event loop using amongoc_loop_vtable::call_soon().

amongoc_emitter [[type(nil)]] amongoc_schedule_later(
amongoc_loop *loop,
timespec duration,
)#

Schedule a completion after duration has elapsed.

Parameters:
  • loop – The event loop that controls the timer and will complete the operation.

  • duration – The amount of time to delay the operation.

Returns:

An amongoc_emitter that resolves with amongoc_nil upon success after duration has elapsed. Note that the operation may resolve earlier in case of error or cancellation.

Allocation:

This operation uses the event loop’s allocator.

Header:

amongoc/async.h

amongoc_emitter amongoc_timeout(
amongoc_loop *loop,
amongoc_emitter [[transfer]] em,
timespec duration,
)#

Attach a timeout to the asynchronous operation em.

Parameters:
  • loop – The event loop that will handle the timeout.

  • em[[transfer]] An amongoc_emitter for an operation that will be cancelled if it exceeds the duration of the timeout.

  • duration – The timeout duration.

Returns:

A new emitter \(R\) representing the operation with the timeout.

Allocation:

This operation uses the event loop’s allocator.

Header:

amongoc/async.h

If the timeout is hit before the em resolves, then em will be cancelled immediately. After cancellation completes, \(R\) will resolve with a status of ETIMEDOUT and value amongoc_nil.

If the timeout does not hit before em resolves, then the result status and value from em will be emitted by \(R\).

Important

If the operation em does not properly support cancellation, then the timeout cannot work, as the composed operation must wait for the em operation to resolve after the cancellation has been requested. (All default operations provided by amongoc support cancellation, unless otherwise specified.)

amongoc_emitter amongoc_alloc_failure()#

Obtain an emitter that immediately resolves with a generic ENOMEM for its completion status. This may be returned by any API returning an amongoc_emitter that requires memory allocation.

Allocation:

This function and the returned emitter do not allocate memory.

Header:

amongoc/async.h

amongoc_operation amongoc_tie(
amongoc_emitter [[transfer, type(T)]] em,
amongoc_status *[[storage]] st,
amongoc_box *[[storage, type(T)]] value,
mlib_allocator alloc,
)#

Create an amongoc_operation object that captures the emitter’s results in the given locations.

Parameters:
  • em[[transfer]] The operation to be executed.

  • st[[storage]] Pointer to an amongoc_status object to receive the emitter’s final status. If NULL, the status will be discarded.

  • value[[storage]] Pointer to an amongoc_box object that will hold the emitter’s result. If NULL, the emitter’s result value will be destoyed instead of stored.

  • alloc – Allocator used for operation state.

Header:

amongoc/async.h

Important

It is essential that the two pointed-to locations be alive and valid until the returned amongoc_operation completes or is destroyed.

amongoc_operation amongoc_detach(
amongoc_emitter [[transfer]] em,
mlib_allocator alloc,
)#

Create a “detached” operation for an emitter.

Parameters:
  • em – The emitter to be detached.

  • alloc – Allocator used for operation state.

Header:

amongoc/async.h

The returned operation object can be launched with amongoc_start(). The final result value from the emitter em will be immediatly destroyed when it resolves.

Hint

This function is equivalent to amongoc_tie(em, nullptr, nullptr, alloc)

Types#

type amongoc_then_transformer#
type amongoc_let_transformer#

These are function pointer types with the following signatures:

amongoc_box [[type(Out)]] __then_signature(
amongoc_box [[transfer, type(User)]] userdata,
amongoc_status *inout_st,
amongoc_box [[transfer, type(In)]] value,
)#
amongoc_emitter [[type(Out)]] __let_signature(
amongoc_box [[transfer, type(User)]] userdata,
amongoc_status st,
amongoc_box [[transfer, type(In)]] value,
)#

The function pointer types used to transform an emitter result for amongoc_then() and amongoc_let(), respectively.

Header:

amongoc/async.h

The following parameters are used:

amongoc_box [[transfer, type(User)]] userdata#

The userdata value that was given to amongoc_then()/amongoc_let().

Note the [[transfer]] attribute: It is responsibility of the callee to clean up this object.

Note

If the transformer function is not called but the associated emitter is destroyed or resolves in another way, then the userdata will be destroyed automatically using amongoc_box_destroy(). For this reason: Be sure to attach a destructor to your userdata, since it may need to be cleaned up by code that is outside of your control.

amongoc_status st#
amongoc_status *inout_st#

The resolve status of the input emitter.

For amongoc_then(), inout_st is a non-null pointer to a status object that may be modified by the transformer. The modified status will then be used as the result status of the composed emitter.

amongoc_box [[transfer, type(In)]] value#

The result value that was emitted by the input emitter. Note the [[transfer]] attribute: It is responsibility of the callee to clean up this object.

The then transformer is expected to return an amongoc_box, while the let transformer must return an amongoc_emitter. For an explanation of this behavior, refer to amongoc_then() and amongoc_let(), respectively.

Constants#

enum amongoc_async_flags#

Flags to control the behavior of amongoc_then() and amongoc_let()

Header:

amongoc/async.h

enumerator amongoc_async_default#

No special behavior.

enumerator amongoc_async_forward_errors#

If this flag is specified and the input emitter resolves with an error status (checked using amongoc_is_error()), then the transformation function will be skipped and the error from the emitter will be immediately forwarded to the next handler.