1 #include "uv.h"
2 #include "sync_helpers.h"
3 #include "uv_mapping.h"
4 #include "uvwasi_alloc.h"
5
6 typedef struct free_handle_data_s {
7 uvwasi_t* uvwasi;
8 int done;
9 } free_handle_data_t;
10
free_handle_cb(uv_handle_t * handle)11 static 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
free_handle_sync(struct uvwasi_s * uvwasi,uv_handle_t * handle)17 int 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
do_stream_shutdown(uv_shutdown_t * req,int status)30 static 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
shutdown_stream_sync(struct uvwasi_s * uvwasi,uv_stream_t * stream,shutdown_data_t * shutdown_data)37 int 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
recv_alloc_cb(uv_handle_t * handle,size_t suggested_size,uv_buf_t * buf)57 static 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
do_stream_recv(uv_stream_t * stream,ssize_t nread,const uv_buf_t * buf)64 void 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
read_stream_sync(struct uvwasi_s * uvwasi,uv_stream_t * stream,recv_data_t * recv_data)72 int 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