-
Notifications
You must be signed in to change notification settings - Fork 0
/
promise.h
149 lines (135 loc) · 5.31 KB
/
promise.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#ifndef __PROMISE_H
#define __PROMISE_H
#include <stdbool.h>
#include <stdarg.h>
typedef void* promise_manager_handle_t;
typedef void* promise_handle_t;
promise_manager_handle_t promise_manager_new();
void promise_manager_free(promise_manager_handle_t manager);
/**
* @brief Create a new promise
*
* @param manager
* @return promise_handle_t
*/
promise_handle_t promise_new(promise_manager_handle_t manager);
/**
* @brief Destroy a promise. The promise can be at any state.
* Neither then nor catch will be called after this.
* If the proimse is resovled or rejected and the free_data function is set.
* The data will be freed to prevent any untracked data.
*
* @param manager
* @param promise
*/
void promise_destroy(promise_manager_handle_t manager, promise_handle_t promise);
typedef union
{
void* ptr;
double number;
bool boolean;
} promise_data_t;
/**
* @brief Resolve a promise. A promise can only be resolved or rejected once.
*
* @param manager
* @param promise
* @param data User of this should know the type of it.
* @param free_data Called when the promise is destroyed or is handled w/o data taken over.
* @param ctx ctx for free_data
* @return int 0 on success, -1 on error
*/
int promise_resolve(
promise_manager_handle_t manager, promise_handle_t promise,
promise_data_t data, void(*free_data)(void*,void*), void* ctx);
/**
* @brief Reject a promise. A promise can only be resolved or rejected once.
*
* @param manager
* @param promise
* @param reason User of this should know the type of it.
* @param free_reason Called when the promise is destroed or is handled w/o data taken over.
* @param ctx ctx for free_reason
* @return int 0 on success, -1 on error
*/
int promise_reject(
promise_manager_handle_t manager, promise_handle_t promise,
promise_data_t reason, void(*free_reason)(void*,void*), void* ctx);
typedef void(*promise_then_handler_t)(promise_data_t data, void* ctx, void(*free_ptr)(void*, void*), void* free_ctx);
typedef void(*promise_catch_handler_t)(promise_data_t reason, void* ctx, void(*free_ptr)(void*, void*), void* free_ctx);
/**
* @brief Assign then and catch handler.
* The promise will be freed after all the handlers assigned to it is called.
* The then handler will be called under the following conditions:
* 1. If the promise is resolved later.
* 2. If the promise is already resolved but not assigned with a then handler.
* The catch handler will be called under the following conditions:
* 1. If the promise is rejected later.
* 2. If the promise is already rejected but not assigned with a catch handler.
*
* @param manager
* @param promise
* @param then not nullable
* @param then_ctx
* @param takeover_data If this is set. The data will not be freed when the promise is freed
* @param catch not nullable
* @param catch_ctx
* @param takeover_reason If this is set. The reason will not be freed when the promise is freed
* @return int 0 on success, -1 on error
*/
int promise_await(
promise_manager_handle_t manager, promise_handle_t promise,
promise_then_handler_t then, void* then_ctx, bool takeover_data,
promise_catch_handler_t catch, void* catch_ctx, bool takeover_reason);
typedef struct
{
promise_data_t data;
struct
{
void(*free_ptr)(void*,void*);
void* free_ctx;
} internal;
} promise_data_list_item_t;
typedef struct
{
int length;
promise_data_list_item_t* items;
} promise_data_list_t;
/**
* @brief Create a new promise. Which:
* will be resolved if all of the promises are resolved.
* will be rejected if any of the promises is rejected.
* The resolved value is a list of all the sub promises' resolve values.
* The rejected reason is the first rejected sub promise's reject reason.
* @attention Sub promises are strongly linked to this promise. DO NOT use them for other purposes.
* @attention Sub promises' data are taken over by default.
* @attention User MUST handle the data list content
* @attention User MUST NOT use the data list outside and free_data of then
*
* @param manager
* @param n number of promises
* @param ... promises
* @return promise_handle_t or NULL on error
*/
promise_handle_t promise_all(promise_manager_handle_t manager, int n,...);
promise_handle_t promise_all_v(promise_manager_handle_t manager, int n, va_list args);
promise_handle_t promise_all_n(promise_manager_handle_t manager, int n, promise_handle_t* promises);
/**
* @brief Create a new promise. Which:
* will be resolved if any of the promises is resolved.
* will be rejected if all of the promises are rejected.
* The resolved value is the first resovled sub promise's resolve value
* The rejected reason is a list of all the sub promises' reject reasons
* @attention Sub promises are strongly linked to this promise. DO NOT use them for other purposes.
* @attention Sub promises' reject reason are taken over by default
* @attention Sub promises MUST have their free_data set if it is allocated.
*
* @param manager
* @param n number of promises
* @param ... promises
* @return promise_handle_t or NULL on error
*/
promise_handle_t promise_any(promise_manager_handle_t manager, int n,...);
promise_handle_t promise_any_v(promise_manager_handle_t manager, int n, va_list args);
promise_handle_t promise_any_n(promise_manager_handle_t manager, int n, promise_handle_t* promises);
#endif