Lely core libraries 2.3.4
|
This file is part of the event library; it contains the implementation of the futures and promises functions. More...
#include "ev.h"
#include <lely/libc/stdatomic.h>
#include <lely/libc/stddef.h>
#include <lely/libc/threads.h>
#include <lely/ev/exec.h>
#include <lely/ev/future.h>
#include <lely/ev/task.h>
#include <lely/util/errnum.h>
#include <lely/util/util.h>
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
Go to the source code of this file.
Data Structures | |
struct | ev_future |
A future. More... | |
struct | ev_promise |
A promise. More... | |
struct | ev_future_when_all |
struct | ev_future_when_any |
Enumerations | |
enum | ev_future_state { EV_FUTURE_WAITING , EV_FUTURE_SETTING , EV_FUTURE_READY } |
The state of a future. More... | |
Functions | |
ev_promise_t * | ev_promise_create (size_t size, ev_promise_dtor_t *dtor) |
Constructs a new promise with an optional empty shared state. More... | |
ev_promise_t * | ev_promise_acquire (ev_promise_t *promise) |
Acquires a reference to a promise. More... | |
void | ev_promise_release (ev_promise_t *promise) |
Releases a reference to a promise. More... | |
int | ev_promise_is_unique (const ev_promise_t *promise) |
Returns 1 if promise is the only reference to the promise and no references to its associated future are held. More... | |
void * | ev_promise_data (const ev_promise_t *promise) |
Returns a pointer to the shared state of a promise. | |
int | ev_promise_set (ev_promise_t *promise, void *value) |
Satiesfies a promise, if it was not aready satisfied, and stores the specified value for retrieval by ev_future_get(). More... | |
int | ev_promise_set_acquire (ev_promise_t *promise) |
Checks if the specified promise can be satisfied by the caller and, if so, prevents others from satisfying the promise. More... | |
void | ev_promise_set_release (ev_promise_t *promise, void *value) |
Satisfies a promise prepared by ev_promise_set_acquire(), and stores the specified value for retrieval by ev_future_get(). More... | |
ev_future_t * | ev_promise_get_future (ev_promise_t *promise) |
Returns (a reference to) a future associated with the specified promise. | |
ev_future_t * | ev_future_acquire (ev_future_t *future) |
Acquires a reference to a future. More... | |
void | ev_future_release (ev_future_t *future) |
Releases a reference to a future. More... | |
int | ev_future_is_unique (const ev_future_t *future) |
Returns 1 if future is the only reference to the future and no references to its associated promise are held. More... | |
int | ev_future_is_ready (const ev_future_t *future) |
Checks if the specified future is ready, i.e., its associated promise has been satisfied. More... | |
void * | ev_future_get (const ev_future_t *future) |
Returns the result of a ready future. More... | |
void | ev_future_submit (ev_future_t *future, struct ev_task *task) |
Submits a task to be executed once the specified future is ready. More... | |
size_t | ev_future_cancel (ev_future_t *future, struct ev_task *task) |
Cancels the specified task submitted with ev_future_submit(), if it has not yet been scheduled for execution, or all tasks if task is NULL. More... | |
size_t | ev_future_abort (ev_future_t *future, struct ev_task *task) |
Aborts the specified task submitted with ev_future_submit(), if it has not yet been scheduled for execution, or all tasks if task is NULL. More... | |
ev_future_t * | ev_future_when_all (ev_exec_t *exec, ev_future_t *future,...) |
Equivalent to ev_future_when_all_n(), except that it accepts a variable number of arguments instead of a list of futures. More... | |
ev_future_t * | ev_future_when_all_v (ev_exec_t *exec, ev_future_t *future, va_list ap) |
Equivalent to ev_future_when_all(), except that it accepts a va_list instead of a variable number of arguments. | |
ev_future_t * | ev_future_when_all_n (ev_exec_t *exec, size_t n, ev_future_t *const *futures) |
Creates a future that becomes ready when all of the input futures become ready or one of the input futures is abandoned before becoming ready. More... | |
ev_future_t * | ev_future_when_any (ev_exec_t *exec, ev_future_t *future,...) |
Equivalent to ev_future_when_any_n(), except that it accepts a variable number of arguments instead of a list of futures. More... | |
ev_future_t * | ev_future_when_any_v (ev_exec_t *exec, ev_future_t *future, va_list ap) |
Equivalent to ev_future_when_any(), except that it accepts a va_list instead of a variable number of arguments. | |
ev_future_t * | ev_future_when_any_n (ev_exec_t *exec, size_t n, ev_future_t *const *futures) |
Creates a future that becomes ready when at least one of the input futures becomes ready or is abandoned. More... | |
This file is part of the event library; it contains the implementation of the futures and promises functions.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Definition in file future.c.
enum ev_future_state |
The state of a future.
Enumerator | |
---|---|
EV_FUTURE_WAITING | The future is waiting. |
EV_FUTURE_SETTING | The promise is in the process of being satisfied (i.e., ev_promise_set_acquire() has been invoked). |
EV_FUTURE_READY | The future is ready (i.e., ev_promise_set_release() has been invoked). |
ev_promise_t * ev_promise_create | ( | size_t | size, |
ev_promise_dtor_t * | dtor | ||
) |
Constructs a new promise with an optional empty shared state.
The promise is destroyed once the last reference to it is released.
size | the size (in bytes) of the shared state (can be 0). |
dtor | a pointer to the function used to destroy the shared state (can be NULL). |
ev_promise_t * ev_promise_acquire | ( | ev_promise_t * | promise | ) |
Acquires a reference to a promise.
If promise is NULL, this function has no effect.
void ev_promise_release | ( | ev_promise_t * | promise | ) |
Releases a reference to a promise.
If this is the last reference to the promise, the promise is destroyed. If no references remain to its associated future, the shared state is destroyed by the destructor provided to ev_promise_create(). The object pointed to by promise MUST NOT be referenced after this function had been invoked.
int ev_promise_is_unique | ( | const ev_promise_t * | promise | ) |
Returns 1 if promise is the only reference to the promise and no references to its associated future are held.
Note that, although the reference count itself is not reliable in multi-threaded environments, optimizations based of whether a reference is unique are reliable.
int ev_promise_set | ( | ev_promise_t * | promise, |
void * | value | ||
) |
Satiesfies a promise, if it was not aready satisfied, and stores the specified value for retrieval by ev_future_get().
This function is equivalent to
int ev_promise_set_acquire | ( | ev_promise_t * | promise | ) |
void ev_promise_set_release | ( | ev_promise_t * | promise, |
void * | value | ||
) |
Satisfies a promise prepared by ev_promise_set_acquire(), and stores the specified value for retrieval by ev_future_get().
It is common for the value to be stored in the shared state (in which case value equals ev_promise_data(promise)
), but this is not required.
ev_future_t * ev_future_acquire | ( | ev_future_t * | future | ) |
Acquires a reference to a future.
If future is NULL, this function has no effect.
void ev_future_release | ( | ev_future_t * | future | ) |
Releases a reference to a future.
If this is the last reference to the future, the future is destroyed. If no references remain to its associated promise, the shared state is destroyed. The object pointed to by future MUST NOT be referenced after this function had been invoked.
int ev_future_is_unique | ( | const ev_future_t * | future | ) |
Returns 1 if future is the only reference to the future and no references to its associated promise are held.
Note that, although the reference count itself is not reliable in multi-threaded environments, optimizations based of whether a reference is unique are reliable.
int ev_future_is_ready | ( | const ev_future_t * | future | ) |
Checks if the specified future is ready, i.e., its associated promise has been satisfied.
void * ev_future_get | ( | const ev_future_t * | future | ) |
Returns the result of a ready future.
Calling this function when the associated promise is not yet satisfied is undefined behavior.
void ev_future_submit | ( | ev_future_t * | future, |
struct ev_task * | task | ||
) |
Submits a task to be executed once the specified future is ready.
This function SHALL NOT block waiting for the future to become ready or the task to be completed. If this function is called with a ready future, the task MAY begin executing before this function returns, depending on the behavior of ev_exec_post() of its associated executor.
size_t ev_future_cancel | ( | ev_future_t * | future, |
struct ev_task * | task | ||
) |
Cancels the specified task submitted with ev_future_submit(), if it has not yet been scheduled for execution, or all tasks if task is NULL.
Canceled tasks are submitted for execution to their associated executor with ev_exec_post(), whether the future is ready or not.
size_t ev_future_abort | ( | ev_future_t * | future, |
struct ev_task * | task | ||
) |
Aborts the specified task submitted with ev_future_submit(), if it has not yet been scheduled for execution, or all tasks if task is NULL.
Aborted tasks are not scheduled for execution.
ev_future_t * ev_future_when_all | ( | ev_exec_t * | exec, |
ev_future_t * | future, | ||
... | |||
) |
Equivalent to ev_future_when_all_n(), except that it accepts a variable number of arguments instead of a list of futures.
The last argument MUST be a NULL pointer.
ev_future_t * ev_future_when_all_n | ( | ev_exec_t * | exec, |
size_t | n, | ||
ev_future_t *const * | futures | ||
) |
Creates a future that becomes ready when all of the input futures become ready or one of the input futures is abandoned before becoming ready.
The result of the created future, once it becomes ready, is a size_t
value containing the number of ready futures or the index of the first abandoned future. If no input futures are specified, a ready future is returned with an empty result (ev_future_get() returns NULL).
This function acquires references to each of the input futures and submits tasks waiting for them to become ready. It is the responsibility of the caller to ensure that these tasks are not aborted with ev_future_abort(), as that would lead to a resource leak.
exec | a pointer the executor used for the waiting tasks. |
n | the number of (pointers to) futures in futures. |
futures | an array of pointers to futures (can be NULL if n is 0). |
ev_future_t * ev_future_when_any | ( | ev_exec_t * | exec, |
ev_future_t * | future, | ||
... | |||
) |
Equivalent to ev_future_when_any_n(), except that it accepts a variable number of arguments instead of a list of futures.
The last argument MUST be a NULL pointer.
ev_future_t * ev_future_when_any_n | ( | ev_exec_t * | exec, |
size_t | n, | ||
ev_future_t *const * | futures | ||
) |
Creates a future that becomes ready when at least one of the input futures becomes ready or is abandoned.
The result of the created future, once it becomes ready, is a size_t
value containing the index of the first ready (or abandoned) future. If no input futures are specified, a ready future is returned with an empty result (ev_future_get() returns NULL).
This function acquires references to each of the input futures and submits tasks waiting for them to become ready. It is the responsibility of the caller to ensure that these tasks are not aborted with ev_future_abort(), as that would lead to a resource leak.
exec | a pointer the executor used for the waiting tasks. |
n | the number of (pointers to) futures in futures. |
futures | an array of pointers to futures (can be NULL if n is 0). |