|
/* |
|
* example demonstrating promises' usage, doesn't actually run as it relies on non-existent uv_channel_t and uv_promise_t, |
|
* is missing some headers and is here for api usage demonstration purposes only |
|
*/ |
|
|
|
typedef struct driver_s driver_t; |
|
typedef struct request_s request_t; |
|
|
|
void io_thread(void* arg); |
|
|
|
struct driver_s { |
|
uv_thread_t* io_tid; |
|
uv_channel_t* pipe; |
|
}; |
|
|
|
driver_t* |
|
driver_new() |
|
{ |
|
driver_t* self = calloc(1, sizeof(driver_t)); |
|
uv_channel_t* pipe = calloc(1, sizeof(uv_channel_t)); |
|
|
|
ASSERT(self); |
|
ASSERT(pipe); |
|
|
|
self->pipe = pipe; |
|
|
|
ASSERT(uv_thread_create(self->io_tid, io_thread, pipe) == 0); |
|
|
|
return self; |
|
} |
|
|
|
uv_promise_t* |
|
driver_execute(driver_t* self, const char* statement) |
|
{ |
|
uv_promise_t* promise = calloc(1, sizeof(uv_promise_t)); |
|
request_t* request = calloc(1, sizeof(request_t)); |
|
|
|
ASSERT(promise); |
|
ASSERT(request); |
|
|
|
uv_promise_init(promise); |
|
|
|
request->statement = statement; |
|
request->promise = promise; |
|
|
|
uv_channel_send(self->pipe, request); |
|
|
|
return promise; |
|
} |
|
|
|
void |
|
driver_destroy(driver_t** self_p) |
|
{ |
|
ASSERT(self_p) |
|
|
|
if (*self_p) { |
|
driver_t* self = *self_p; |
|
|
|
uv_handle_close(self->pipe, free); |
|
free(self); |
|
|
|
*self_p = NULL; |
|
} |
|
} |
|
|
|
void |
|
on_timeout(uv_timer_t* handle) |
|
{ |
|
ASSERT(handle); |
|
|
|
(uv_promise_t*) promise = handle->data; |
|
(int*) result = malloc(sizeof(int)); |
|
|
|
ASSERT(result); |
|
|
|
*result = 5; |
|
|
|
uv_promise_fulfil(promise, result); |
|
} |
|
|
|
struct request_s { |
|
const char* statement; |
|
uv_promise_t* promise; |
|
}; |
|
|
|
void |
|
handle_request(uv_channel_t* chan, void* arg) |
|
{ |
|
request_t* request = (request_t*) arg; |
|
printf(stdout, "io thread received request for statement %s", |
|
(char*) request->statement); |
|
|
|
// sleep for 3 seconds |
|
uv_timer_t* timeout = calloc(1, sizeof(uv_timer_t)); |
|
|
|
ASSERT(timeout); |
|
|
|
// promise will be resolved inside timeout handler |
|
timeout->data = request->promise; |
|
|
|
uv_timer_init(uv_loop_default(), timeout); |
|
uv_timer_start(timeout, on_timeout, 3000, 0); |
|
} |
|
|
|
int main(int argc, char const *argv[]) |
|
{ |
|
driver_t* driver = driver_new(); |
|
promise_t* future = driver_execute("SELECT * FROM table"); |
|
|
|
promise_wait(future); |
|
|
|
fprintf(stderr, "query finished\n"); |
|
|
|
promise_result_t result = promise_result(future); |
|
|
|
if (result.status == UV_PROMISE_FULFILLED) |
|
fprintf(stderr, "query returned %d\n", (int) *result.result); |
|
else |
|
fprintf(stderr, "query failed\n"); |
|
|
|
driver_destroy(&driver); |
|
|
|
return 0; |
|
} |
|
|
|
void |
|
io_thread(void* arg) |
|
{ |
|
ASSERT(arg); |
|
|
|
uv_loop_t* loop = uv_loop_default(); |
|
uv_channel_t* pipe = (uv_channel_t*) arg; |
|
|
|
uv_channel_init(loop, pipe, handle_request); |
|
uv_loop_run(loop); |
|
} |