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