Modules | Data Structures | Functions | Variables
Eina Promises

Promises are a programming paradigm that simplifies synchronization when concurrent execution is present. More...

Modules

 Eina Futures
 Methods and structures dealing with Eina_Future.
 

Data Structures

struct  Eina_Promise
 An opaque structure representing a piece of data that will be available at a later point. More...
 

Functions

EAPI Eina_Promiseeina_promise_new (Eina_Future_Scheduler *scheduler, Eina_Promise_Cancel_Cb cancel_cb, const void *data)
 Creates a new promise. More...
 
EAPI Eina_Promiseeina_promise_continue_new (const Eina_Future *dead_future, Eina_Promise_Cancel_Cb cancel_cb, const void *data)
 Creates a new promise from a dead_future. More...
 
EAPI void eina_promise_resolve (Eina_Promise *p, Eina_Value value)
 Resolves a promise. More...
 
EAPI void eina_promise_reject (Eina_Promise *p, Eina_Error err)
 Rejects a promise. More...
 

Variables

EAPI const Eina_Value_Type EINA_VALUE_TYPE_PROMISE
 Value type for Eina_Value's containing an Eina_Promise.
 

Detailed Description

Promises are a programming paradigm that simplifies synchronization when concurrent execution is present.

Since C does not natively support Promises the Eina library provides the Eina_Promise and Eina_Future objects.

In procedural languages like C if you need a value which is not yet available, for instance because it takes a long time to calculate or has to be fetched from a remote server, you typically have to wait.

Other languages however can return a Promise and continue execution immediately. A promise acts as a placeholder for the requested value: the value is not available yet but will be at some point in the future.

With a promise in hand you can attach callbacks to be triggered when the value becomes available (i.e. when the promise is fulfilled) and then continue your calculations. You can even pass the promise to other methods which will then be executed as values become available, forming complex chains.

An Eina_Promise can be considered as an object with the sole purpose of emitting the "Promise Resolved" event. Eina_Future are callbacks attached to this object to be called when the event is emitted. The promised value is passed to the callbacks whenever it's available.

Here's a typical example:

#include <Ecore.h>
static void
_promise_cancel(void *data, Eina_Promise *p EINA_UNUSED)
{
Ctx *ctx = data;
// In case the promise is canceled we must stop the timer!
ecore_timer_del(ctx->timer);
free(ctx);
}
static Eina_Bool
_promise_resolve(void *data)
{
Ctx *ctx = data;
eina_value_set(&v, "Promise resolved");
free(ctx);
return EINA_FALSE;
}
promise_create(Eina_Future_Scheduler *scheduler)
{
Ctx *ctx = malloc(sizeof(Ctx));
// A timer is scheduled in order to resolve the promise
ctx->timer = ecore_timer_add(122, _promise_resolve, ctx);
// The _promise_cancel() will be used to clean ctx if the promise is canceled.
ctx->p = eina_promise_new(scheduler, _promise_cancel, ctx);
return ctx->p;
}

Function Documentation

◆ eina_promise_new()

EAPI Eina_Promise* eina_promise_new ( Eina_Future_Scheduler scheduler,
Eina_Promise_Cancel_Cb  cancel_cb,
const void *  data 
)

Creates a new promise.

This function creates a new promise which can be used to create a future using eina_future_new(). Every time a promise is created an Eina_Promise_Cancel_Cb must be provided which is used to free resources that were created.

A promise may be canceled directly by calling:

That is, canceling any future that is chained to receive the results.

However promises can be canceled indirectly by other entities. These other entities will call eina_future_cancel() themselves, however you may not be aware of that. Some common sources of indirect cancellations:

  • A subsystem was shutdown, canceling all pending futures (i.e.: ecore_shutdown())
  • An EO object was linked to the promise or future, then if the object dies (last reference is gone), then the pending promises and futures will be canceled.
  • Some other entity (library provider or library user) chained and canceled his future, which will result in your future being canceled.

Since a promise may be canceled indirectly (by code sections that goes beyond your scope) you should always provide a cancel callback, even if you think you'll not need it.

If you already have a value and want to create a future that will resolve to it directly use the eina_future_resolved(), it has the same effect as creating a promise and immediately resolving it.

Parameters
[in,out]schedulerThe scheduler.
[in]cancel_cbA callback used to inform that the promise was canceled. Use this callback to free data. cancel_cb must not be NULL !
[in]dataData to cancel_cb.
Returns
A promise or NULL on error.
See also
eina_future_cancel()
eina_future_new()
eina_promise_continue_new()
eina_promise_resolve()
eina_promise_reject()
eina_promise_as_value()
Eina_Future_Scheduler
Eina_Future_Schedule_Entry
Eina_Future_Scheduler_Cb

References DBG, eina_mempool_calloc(), EINA_SAFETY_ON_NULL_RETURN_VAL, _Eina_Future_Scheduler::recall, and _Eina_Future_Scheduler::schedule.

Referenced by eina_future_as_value(), eina_future_rejected(), eina_future_resolved(), and eina_promise_all_iterator().

◆ eina_promise_continue_new()

EAPI Eina_Promise* eina_promise_continue_new ( const Eina_Future dead_future,
Eina_Promise_Cancel_Cb  cancel_cb,
const void *  data 
)

Creates a new promise from a dead_future.

This function creates a new promise from a future currently being resolved which can be used to create a Eina_Value with eina_promise_as_value(). Every time a promise is created an Eina_Promise_Cancel_Cb must be provided which is used to free resources that were created.

A promise may be canceled directly by calling:

That is, canceling any future that is chained to receive the results.

However promises can be canceled indirectly by other entities. These other entities will call eina_future_cancel() themselves, however you may not be aware of that. Some common sources of indirect cancellations:

  • A subsystem was shutdown, canceling all pending futures (i.e.: ecore_shutdown())
  • An EO object was linked to the promise or future, then if the object dies (last reference is gone), then the pending promises and futures will be canceled.
  • Some other entity (library provider or library user) chained and canceled his future, which will result in your future being canceled.

Since a promise may be canceled indirectly (by code sections that goes beyond your scope) you should always provide a cancel callback, even if you think you'll not need it.

Here's a typical example:

_future_resolve(void *data, const Eina_Value v, const Eina_Future *dead_future)
{
p = eina_promise_continue_new(dead_future, _promise_cancel, NULL);
}

If you already have a value and want to create a future that will resolve to it directly use the eina_future_resolved(), it has the same effect as creating a promise and immediately resolving it.

Note
This function is to be used solely inside of a future resolve callback with the Eina_Value being returned from it.
Parameters
[in]dead_futureThe future being resolved to get a scheduler from.
[in]cancel_cbA callback used to inform that the promise was canceled. Use this callback to free data. cancel_cb must not be NULL.
[in]dataData to cancel_cb.
Returns
A promise or NULL on error.
See also
eina_future_cancel()
eina_future_new()
eina_promise_new()
eina_promise_resolve()
eina_promise_reject()
eina_promise_as_value()
Eina_Future_Scheduler
Eina_Future_Schedule_Entry
Eina_Future_Scheduler_Cb

References DBG, eina_mempool_calloc(), EINA_SAFETY_ON_NULL_RETURN_VAL, and EINA_SAFETY_ON_TRUE_RETURN_VAL.

◆ eina_promise_resolve()

EAPI void eina_promise_resolve ( Eina_Promise p,
Eina_Value  value 
)

Resolves a promise.

This function schedules a resolve event in a safe context (main loop or some platform defined safe context), whenever possible the future callbacks will be dispatched.

Parameters
[in,out]pA promise to resolve.
[in]valueThe value to be delivered.

Note that the value contents must survive this function scope, that is, do not use stack allocated blobs, arrays, structures or types that keep references to memory you give. Values will be automatically cleaned up using eina_value_flush() once they are unused (no more future or futures returned a new value).

See also
eina_promise_new()
eina_promise_reject()
eina_promise_as_value()

References eina_value_flush().

Referenced by eina_future_resolved().

◆ eina_promise_reject()

EAPI void eina_promise_reject ( Eina_Promise p,
Eina_Error  err 
)

Rejects a promise.

This function schedules a reject event in a safe context (main loop or some platform defined safe context), whenever possible the future callbacks will be dispatched.

Parameters
[in,out]pA promise to reject.
[in]errAn Eina_Error value
Note
Internally this function will create an Eina_Value with type EINA_VALUE_TYPE_ERROR.
See also
eina_promise_new()
eina_promise_resolve()
eina_promise_as_value()

References DBG, eina_error_msg_get(), EINA_SAFETY_ON_FALSE_GOTO, eina_value_flush(), eina_value_set(), eina_value_setup(), and EINA_VALUE_TYPE_ERROR.

Referenced by eina_future_rejected().