1#include "uv.h"
2#include "sync_helpers.h"
3#include "uv_mapping.h"
4#include "uvwasi_alloc.h"
5
6typedef struct free_handle_data_s {
7  uvwasi_t* uvwasi;
8  int done;
9} free_handle_data_t;
10
11static void free_handle_cb(uv_handle_t* handle) {
12  free_handle_data_t* free_handle_data = uv_handle_get_data((uv_handle_t*) handle);
13  uvwasi__free(free_handle_data->uvwasi, handle);
14  free_handle_data->done = 1;
15}
16
17int free_handle_sync(struct uvwasi_s* uvwasi, uv_handle_t* handle) {
18  free_handle_data_t free_handle_data = { uvwasi, 0 };
19  uv_handle_set_data(handle, (void*) &free_handle_data);
20  uv_close(handle, free_handle_cb);
21  uv_loop_t* handle_loop = uv_handle_get_loop(handle);
22  while(!free_handle_data.done) {
23    if (uv_run(handle_loop, UV_RUN_ONCE) == 0) {
24      break;
25    }
26  }
27  return UVWASI_ESUCCESS;
28}
29
30static void do_stream_shutdown(uv_shutdown_t* req, int status) {
31  shutdown_data_t* shutdown_data;
32  shutdown_data = uv_handle_get_data((uv_handle_t*) req->handle);
33  shutdown_data->status = status;
34  shutdown_data->done = 1;
35 }
36
37int shutdown_stream_sync(struct uvwasi_s* uvwasi,
38                          uv_stream_t* stream,
39		          shutdown_data_t* shutdown_data) {
40  uv_shutdown_t req;
41  uv_loop_t* stream_loop;
42
43  shutdown_data->done = 0;
44  shutdown_data->status = 0;
45  stream_loop = uv_handle_get_loop((uv_handle_t*) stream);
46
47  uv_handle_set_data((uv_handle_t*) stream, (void*) shutdown_data);
48  uv_shutdown(&req, stream, do_stream_shutdown);
49  while (!shutdown_data->done) {
50    if (uv_run(stream_loop, UV_RUN_ONCE) == 0) {
51      return UVWASI_ECANCELED;
52    }
53  }
54  return UVWASI_ESUCCESS;
55}
56
57static void recv_alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
58  recv_data_t* recv_data;
59  recv_data = uv_handle_get_data(handle);
60  buf->base = recv_data->base;
61  buf->len = recv_data->len;
62}
63
64void do_stream_recv(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
65  recv_data_t* recv_data;
66  recv_data = uv_handle_get_data((uv_handle_t*) stream);
67  uv_read_stop(stream);
68  recv_data->nread = nread;
69  recv_data->done = 1;
70}
71
72int read_stream_sync(struct uvwasi_s* uvwasi,
73                     uv_stream_t* stream,
74	             recv_data_t* recv_data) {
75  uv_loop_t* recv_loop;
76  int r;
77
78  recv_data->nread = 0;
79  recv_data->done = 0;
80  recv_loop = uv_handle_get_loop((uv_handle_t*) stream);
81
82  uv_handle_set_data((uv_handle_t*) stream, (void*) recv_data);
83  r = uv_read_start(stream, recv_alloc_cb, do_stream_recv);
84  if (r != 0) {
85    return uvwasi__translate_uv_error(r);
86  }
87
88  while (!recv_data->done) {
89    if (uv_run(recv_loop, UV_RUN_ONCE) == 0) {
90      return UVWASI_ECANCELED;
91    }
92 }
93
94  return UVWASI_ESUCCESS;
95}
96