Asynchronous Utility APIs#
- <amongoc/async.h> (header file)#
This header contains miscellaneous asynchronous utilities and building blocks.
Functions#
Synchronous Continuations#
- [[1]] amongoc_emitter [[type(U)]] amongoc_then(
- amongoc_emitter [[transfer, type(T)]] in,
- amongoc_then_transformer [[type(In=T, Out=U)]] tr,
- [[2]] amongoc_emitter [[type(U)]] amongoc_then(
- amongoc_emitter [[transfer, type(T)]] in,
- amongoc_box [[transfer, type(User)]] userdata,
- amongoc_then_transformer [[type(In=T, Out=U, User=User)]] tr,
- [[3]] amongoc_emitter [[type(U)]] amongoc_then(
- amongoc_emitter [[transfer, type(T)]] in,
- amongoc_async_flags flags,
- amongoc_then_transformer [[type(In=T, Out=U)]] tr,
- [[4]] amongoc_emitter [[type(U)]] amongoc_then(
- amongoc_emitter [[transfer, type(T)]] in,
- amongoc_async_flags flags,
- amongoc_box [[transfer, type(User)]] userdata,
- amongoc_then_transformer [[type(In=T, Out=U, User=User)]] tr,
- [[5]] amongoc_emitter [[type(U)]] amongoc_then(
- amongoc_emitter [[transfer, type(T)]] in,
- mlib_allocator alloc,
- amongoc_box [[transfer, type(User)]] userdata,
- amongoc_then_transformer [[type(In=T, Out=U, User=User)]] tr,
- [[6]] amongoc_emitter [[type(U)]] amongoc_then(
- amongoc_emitter [[transfer, type(T)]] in,
- 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:
in –
[[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 totr.tr – The transformer callback. See
amongoc_then_transformerfor information.
- Returns:
A new
amongoc_emitter\(R\)- Header:
When the emitter
inresolves, its result status and value will be given totr. The return value fromtrwill become the new result value of the returned emitter \(R\). The transform functiontrmay 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.Overloads:
Equivalent to amongoc_then(in, amongoc_async_default, mlib_default_allocator, amongoc_nil, tr)
Equivalent to amongoc_then(in, amongoc_async_default, mlib_default_allocator, userdata, tr)
Equivalent to amongoc_then(in, flags, mlib_default_allocator, amongoc_nil, tr)
Equivalent to amongoc_then(in, flags, mlib_default_allocator, userdata, tr)
Equivalent to amongoc_then(in, amongoc_async_default, alloc, userdata, tr)
Specifies all five parameters
Note
This is implemented as a C preprocessor macro.
Asynchronous Continuations#
- [[1]] amongoc_emitter [[type(U)]] amongoc_let(
- amongoc_emitter [[transfer, type(T)]] in,
- amongoc_let_transformer [[type(In=T, Out=U)]] tr,
- [[2]] amongoc_emitter [[type(U)]] amongoc_let(
- amongoc_emitter [[transfer, type(T)]] in,
- amongoc_box [[transfer, type(User)]] userdata,
- amongoc_let_transformer [[type(In=T, Out=U, User=User)]] tr,
- [[3]] amongoc_emitter [[type(U)]] amongoc_let(
- amongoc_emitter [[transfer, type(T)]] in,
- amongoc_async_flags flags,
- amongoc_let_transformer [[type(In=T, Out=U)]] tr,
- [[4]] amongoc_emitter [[type(U)]] amongoc_let(
- amongoc_emitter [[transfer, type(T)]] in,
- amongoc_async_flags flags,
- amongoc_box [[transfer, type(User)]] userdata,
- amongoc_let_transformer [[type(In=T, Out=U, User=User)]] tr,
- [[5]] amongoc_emitter [[type(U)]] amongoc_let(
- amongoc_emitter [[transfer, type(T)]] in,
- mlib_allocator alloc,
- amongoc_box [[transfer, type(User)]] userdata,
- amongoc_let_transformer [[type(In=T, Out=U, User=User)]] tr,
- [[6]] amongoc_emitter [[type(U)]] amongoc_let(
- amongoc_emitter [[transfer, type(T)]] in,
- 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 totr.tr – The transformer callback. See
amongoc_let_transformerfor more information.
- Returns:
A new
amongoc_emitter\(R\).- Header:
When the input emitter
emresolves, the transformer functiontrwill 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.
Immediate Completion#
- [[1]] amongoc_emitter [[type(T)]] amongoc_just(
- amongoc_status st,
- amongoc_box [[transfer, type(T)]] value,
- mlib_allocator alloc,
-
[[2]] amongoc_emitter [[type(nil)]] amongoc_just(amongoc_status st)#
- [[3]] amongoc_emitter [[type(T)]] amongoc_just(
- amongoc_box [[transfer, type(T)]] value,
- [[4]] amongoc_emitter [[type(T)]] amongoc_just(
- amongoc_status st,
- amongoc_box [[transfer, type(T)]] value,
- [[5]] amongoc_emitter [[type(T)]] amongoc_just(
- amongoc_box [[transfer, type(T)]] value,
- mlib_allocator alloc,
-
[[6]] amongoc_emitter [[type(nil)]] amongoc_just()#
Create an emitter that will resolve immediately with the given status and result value.
- Parameters:
st – The result status. If omitted,
amongoc_okay.value –
[[transfer]]The result value. If omitted,amongoc_nilalloc – The allocator for the emitter and operation state.
- Allocation:
Signatures (2) and (6) do not allocate. Signatures (3) and (4) use
mlib_default_allocator.- Returns:
A new
amongoc_emitter\(R\) whose result status will bestand result value will bevalue- Header:
Overloads
Specify the status, the result value, and an allocator
Specify only the status. The result value is
amongoc_nil. This overload does not allocate any memory.Specify the result value. Uses the default allocator, with
amongoc_okaystatus.Specify a result status and result value. Uses the default allocator.
Specify a result value and an allocator, with
amongoc_okaystatusResolve with
amongoc_okayandamongoc_nil. Does not allocate.
Note
The returned emitter here is not tied to any event loop, and it will call
amongoc_handler_complete()immediately within the call toamongoc_start()invoked on its associatedamongoc_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, statusstand resultvaluewill always be sent to the handler.
Other#
- 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
stand resultvalue.- 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:
Upon successful completion, the result value from
emwill be immediately destroyed and the emitter \(R\) will resolve withstandvalue. Upon failure (i.e. ifflagsspecify a different behavior), then thevalueobject 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_emitterfor the schedule operation. It will always emitamongoc_nilto its handler.- Allocation:
This operation uses the event loop’s allocator.
- Header:
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
durationhas 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_emitterthat resolves withamongoc_nilupon success afterdurationhas 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_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]]Anamongoc_emitterfor 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:
If the timeout is hit before the
emresolves, thenemwill be cancelled immediately. After cancellation completes, \(R\) will resolve with a status ofETIMEDOUTand valueamongoc_nil.If the timeout does not hit before
emresolves, then the result status and value fromemwill be emitted by \(R\).Important
If the operation
emdoes not properly support cancellation, then the timeout cannot work, as the composed operation must wait for theemoperation to resolve after the cancellation has been requested. (All default operations provided byamongocsupport cancellation, unless otherwise specified.)
-
amongoc_emitter amongoc_alloc_failure()#
Obtain an emitter that immediately resolves with a generic
ENOMEMfor its completion status. This may be returned by any API returning anamongoc_emitterthat requires memory allocation.- Allocation:
This function and the returned emitter do not allocate memory.
- Header:
- amongoc_operation amongoc_tie(
- amongoc_emitter [[transfer]] em,
- amongoc_status *[[storage]] st,
- amongoc_operation amongoc_tie(
- amongoc_emitter [[transfer, type(T)]] em,
- amongoc_box *[[storage, type(T)]] value,
- amongoc_operation amongoc_tie(
- amongoc_emitter [[transfer, type(T)]] em,
- amongoc_status *[[storage]] st,
- amongoc_box *[[storage, type(T)]] value,
- 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_operationobject that captures the emitter’s results in the given locations.- Parameters:
em –
[[transfer]]The operation to be executed.st –
[[storage]]Pointer to anamongoc_statusobject to receive the emitter’s final status. IfNULL, the status will be discarded.value –
[[storage]]Pointer to anamongoc_boxobject that will hold the emitter’s result. IfNULL, the emitter’s result value will be destoyed instead of stored.alloc – Allocator used for operation state.
- Header:
Important
It is essential that the two pointed-to locations be alive and valid until the returned
amongoc_operationcompletes or is destroyed.
-
amongoc_operation amongoc_detach(amongoc_emitter [[transfer]] em)#
- 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:
The returned operation object can be launched with
amongoc_start(). The final result value from the emitteremwill be immediatly destroyed when it resolves.Hint
This function is equivalent to amongoc_tie(em, nullptr, nullptr, alloc)
-
void amongoc_detach_start(amongoc_emitter [[transfer]] em)#
Launch the asynchronous operation defined by an emitter.
- Parameters:
em –
[[transfer]]An emitter that defines an asynchronous control flow to be executed.- Allocation:
The operation state is allocated using
mlib_default_allocator.
This will internally create an
amongoc_operationstate object,start itimmediately, and destroy the operation state when the operation completes.
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()andamongoc_let(), respectively.- Header:
The following parameters are used:
-
amongoc_box [[transfer, type(User)]] userdata#
The
userdatavalue that was given toamongoc_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
userdatawill be destroyed automatically usingamongoc_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_stis 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
thentransformer is expected to return anamongoc_box, while thelettransformer must return anamongoc_emitter. For an explanation of this behavior, refer toamongoc_then()andamongoc_let(), respectively.
Constants#
-
enum amongoc_async_flags#
Flags to control the behavior of
amongoc_then()andamongoc_let()- Header:
-
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.