|
@@ -4,6 +4,7 @@
|
|
|
#include <caml/fail.h>
|
|
|
#include <caml/memory.h>
|
|
|
#include <caml/mlvalues.h>
|
|
|
+#include <caml/minor_gc.h>
|
|
|
|
|
|
#include <stdio.h>
|
|
|
#include <stdlib.h>
|
|
@@ -35,6 +36,7 @@
|
|
|
#define UV_ALLOC_REQ(name, type, cb) \
|
|
|
UV_ALLOC_CHECK(name, type); \
|
|
|
UV_REQ_DATA(UV_UNWRAP(name, type)) = (void *)cb; \
|
|
|
+ /*caml_oldify_one(cb, UV_REQ_DATA_A(UV_UNWRAP(name, type)));*/ \
|
|
|
caml_register_global_root(UV_REQ_DATA_A(UV_UNWRAP(name, type)));
|
|
|
|
|
|
// free a request, remove its callback from GC roots
|
|
@@ -421,71 +423,24 @@ typedef struct {
|
|
|
} u;
|
|
|
} uv_w_handle_t;
|
|
|
|
|
|
-static uv_w_handle_t *alloc_data_fs_event(value cb_fs_event) {
|
|
|
+static uv_w_handle_t *alloc_data(void) {
|
|
|
uv_w_handle_t *data = calloc(1, sizeof(uv_w_handle_t));
|
|
|
if (data != NULL) {
|
|
|
data->cb_close = Val_unit;
|
|
|
caml_register_global_root(&(data->cb_close));
|
|
|
- data->u.fs_event.cb_fs_event = cb_fs_event;
|
|
|
- caml_register_global_root(&(data->u.fs_event.cb_fs_event));
|
|
|
+ data->u.all.cb1 = Val_unit;
|
|
|
+ caml_register_global_root(&(data->u.all.cb1));
|
|
|
+ data->u.all.cb2 = Val_unit;
|
|
|
+ caml_register_global_root(&(data->u.all.cb2));
|
|
|
}
|
|
|
return data;
|
|
|
}
|
|
|
|
|
|
-static uv_w_handle_t *alloc_data_tcp(value cb_read, value cb_connection) {
|
|
|
- uv_w_handle_t *data = calloc(1, sizeof(uv_w_handle_t));
|
|
|
- if (data != NULL) {
|
|
|
- data->cb_close = Val_unit;
|
|
|
- caml_register_global_root(&(data->cb_close));
|
|
|
- data->u.tcp.cb_read = cb_read;
|
|
|
- caml_register_global_root(&(data->u.tcp.cb_read));
|
|
|
- data->u.tcp.cb_connection = cb_connection;
|
|
|
- caml_register_global_root(&(data->u.tcp.cb_connection));
|
|
|
- }
|
|
|
- return data;
|
|
|
-}
|
|
|
-
|
|
|
-static uv_w_handle_t *alloc_data_udp(value cb_read) {
|
|
|
- uv_w_handle_t *data = calloc(1, sizeof(uv_w_handle_t));
|
|
|
- if (data != NULL) {
|
|
|
- data->cb_close = Val_unit;
|
|
|
- caml_register_global_root(&(data->cb_close));
|
|
|
- data->u.udp.cb_read = cb_read;
|
|
|
- caml_register_global_root(&(data->u.udp.cb_read));
|
|
|
- }
|
|
|
- return data;
|
|
|
-}
|
|
|
-
|
|
|
-static uv_w_handle_t *alloc_data_timer(value cb_timer) {
|
|
|
- uv_w_handle_t *data = calloc(1, sizeof(uv_w_handle_t));
|
|
|
- if (data != NULL) {
|
|
|
- data->cb_close = Val_unit;
|
|
|
- caml_register_global_root(&(data->cb_close));
|
|
|
- data->u.timer.cb_timer = cb_timer;
|
|
|
- caml_register_global_root(&(data->u.timer.cb_timer));
|
|
|
- }
|
|
|
- return data;
|
|
|
-}
|
|
|
-
|
|
|
-static uv_w_handle_t *alloc_data_process(value cb_exit) {
|
|
|
- uv_w_handle_t *data = calloc(1, sizeof(uv_w_handle_t));
|
|
|
- if (data != NULL) {
|
|
|
- data->cb_close = Val_unit;
|
|
|
- caml_register_global_root(&(data->cb_close));
|
|
|
- data->u.process.cb_exit = cb_exit;
|
|
|
- caml_register_global_root(&(data->u.process.cb_exit));
|
|
|
- }
|
|
|
- return data;
|
|
|
-}
|
|
|
-
|
|
|
-static uv_w_handle_t *alloc_data_pipe(void) {
|
|
|
- uv_w_handle_t *data = calloc(1, sizeof(uv_w_handle_t));
|
|
|
- if (data != NULL) {
|
|
|
- data->cb_close = Val_unit;
|
|
|
- caml_register_global_root(&(data->cb_close));
|
|
|
- }
|
|
|
- return data;
|
|
|
-}
|
|
|
+#define UV_SET_CB(cb_storage, cb) \
|
|
|
+ do { \
|
|
|
+ cb_storage = cb; \
|
|
|
+ /*caml_oldify_one(cb, &cb_storage);*/ \
|
|
|
+ } while (0)
|
|
|
|
|
|
static void unalloc_data(uv_w_handle_t *data) {
|
|
|
caml_remove_global_root(&(data->cb_close));
|
|
@@ -508,7 +463,7 @@ static void handle_close_cb(uv_handle_t *handle) {
|
|
|
|
|
|
CAMLprim value w_close(value handle, value cb) {
|
|
|
CAMLparam2(handle, cb);
|
|
|
- ((uv_w_handle_t *)UV_HANDLE_DATA(Handle_val(handle)))->cb_close = cb;
|
|
|
+ UV_SET_CB(((uv_w_handle_t *)UV_HANDLE_DATA(Handle_val(handle)))->cb_close, cb);
|
|
|
uv_close(Handle_val(handle), handle_close_cb);
|
|
|
UV_SUCCESS_UNIT;
|
|
|
}
|
|
@@ -549,9 +504,9 @@ CAMLprim value w_fs_event_start(value loop, value path, value recursive, value c
|
|
|
CAMLparam4(loop, path, recursive, cb);
|
|
|
UV_ALLOC_CHECK(handle, uv_fs_event_t);
|
|
|
UV_ERROR_CHECK_C(uv_fs_event_init(Loop_val(loop), FsEvent_val(handle)), free(FsEvent_val(handle)));
|
|
|
- UV_HANDLE_DATA(FsEvent_val(handle)) = alloc_data_fs_event(cb);
|
|
|
- if (UV_HANDLE_DATA(FsEvent_val(handle)) == NULL)
|
|
|
+ if ((UV_HANDLE_DATA(FsEvent_val(handle)) = alloc_data()) == NULL)
|
|
|
UV_ERROR(0);
|
|
|
+ UV_SET_CB(UV_HANDLE_DATA_SUB(FsEvent_val(handle), fs_event).cb_fs_event, cb);
|
|
|
UV_ERROR_CHECK_C(
|
|
|
uv_fs_event_start(FsEvent_val(handle), handle_fs_event_cb, String_val(path), Bool_val(recursive) ? UV_FS_EVENT_RECURSIVE : 0),
|
|
|
{ unalloc_data(UV_HANDLE_DATA(FsEvent_val(handle))); free(FsEvent_val(handle)); }
|
|
@@ -565,7 +520,7 @@ CAMLprim value w_fs_event_stop(value handle, value cb) {
|
|
|
uv_fs_event_stop(FsEvent_val(handle)),
|
|
|
{ unalloc_data(UV_HANDLE_DATA(FsEvent_val(handle))); free(FsEvent_val(handle)); }
|
|
|
);
|
|
|
- ((uv_w_handle_t *)UV_HANDLE_DATA(FsEvent_val(handle)))->cb_close = cb;
|
|
|
+ UV_SET_CB(((uv_w_handle_t *)UV_HANDLE_DATA(FsEvent_val(handle)))->cb_close, cb);
|
|
|
uv_close(Handle_val(handle), handle_close_cb);
|
|
|
UV_SUCCESS_UNIT;
|
|
|
}
|
|
@@ -642,7 +597,7 @@ CAMLprim value w_shutdown(value stream, value cb) {
|
|
|
|
|
|
CAMLprim value w_listen(value stream, value backlog, value cb) {
|
|
|
CAMLparam3(stream, backlog, cb);
|
|
|
- UV_HANDLE_DATA_SUB(Stream_val(stream), stream).cb_connection = cb;
|
|
|
+ UV_SET_CB(UV_HANDLE_DATA_SUB(Stream_val(stream), stream).cb_connection, cb);
|
|
|
UV_ERROR_CHECK(uv_listen(Stream_val(stream), Int_val(backlog), handle_stream_cb_connection));
|
|
|
UV_SUCCESS_UNIT;
|
|
|
}
|
|
@@ -657,7 +612,7 @@ CAMLprim value w_write(value stream, value data, value cb) {
|
|
|
|
|
|
CAMLprim value w_read_start(value stream, value cb) {
|
|
|
CAMLparam2(stream, cb);
|
|
|
- UV_HANDLE_DATA_SUB(Stream_val(stream), stream).cb_read = cb;
|
|
|
+ UV_SET_CB(UV_HANDLE_DATA_SUB(Stream_val(stream), stream).cb_read, cb);
|
|
|
UV_ERROR_CHECK(uv_read_start(Stream_val(stream), handle_stream_cb_alloc, handle_stream_cb_read));
|
|
|
UV_SUCCESS_UNIT;
|
|
|
}
|
|
@@ -693,8 +648,7 @@ CAMLprim value w_tcp_init(value loop) {
|
|
|
CAMLparam1(loop);
|
|
|
UV_ALLOC_CHECK(handle, uv_tcp_t);
|
|
|
UV_ERROR_CHECK_C(uv_tcp_init(Loop_val(loop), Tcp_val(handle)), free(Tcp_val(handle)));
|
|
|
- UV_HANDLE_DATA(Tcp_val(handle)) = alloc_data_tcp(Val_unit, Val_unit);
|
|
|
- if (UV_HANDLE_DATA(Tcp_val(handle)) == NULL)
|
|
|
+ if ((UV_HANDLE_DATA(Tcp_val(handle)) = alloc_data()) == NULL)
|
|
|
UV_ERROR(0);
|
|
|
UV_SUCCESS(handle);
|
|
|
}
|
|
@@ -715,8 +669,7 @@ CAMLprim value w_tcp_accept(value loop, value server) {
|
|
|
CAMLparam2(loop, server);
|
|
|
UV_ALLOC_CHECK(client, uv_tcp_t);
|
|
|
UV_ERROR_CHECK_C(uv_tcp_init(Loop_val(loop), Tcp_val(client)), free(Tcp_val(client)));
|
|
|
- UV_HANDLE_DATA(Tcp_val(client)) = alloc_data_tcp(Val_unit, Val_unit);
|
|
|
- if (UV_HANDLE_DATA(Tcp_val(client)) == NULL)
|
|
|
+ if ((UV_HANDLE_DATA(Tcp_val(client)) = alloc_data()) == NULL)
|
|
|
UV_ERROR(0);
|
|
|
UV_ERROR_CHECK_C(uv_accept(Stream_val(server), Stream_val(client)), free(Tcp_val(client)));
|
|
|
UV_SUCCESS(client);
|
|
@@ -831,8 +784,7 @@ CAMLprim value w_udp_init(value loop) {
|
|
|
CAMLparam1(loop);
|
|
|
UV_ALLOC_CHECK(handle, uv_udp_t);
|
|
|
UV_ERROR_CHECK_C(uv_udp_init(Loop_val(loop), Udp_val(handle)), free(Udp_val(handle)));
|
|
|
- UV_HANDLE_DATA(Udp_val(handle)) = alloc_data_udp(Val_unit);
|
|
|
- if (UV_HANDLE_DATA(Udp_val(handle)) == NULL)
|
|
|
+ if ((UV_HANDLE_DATA(Udp_val(handle)) = alloc_data()) == NULL)
|
|
|
UV_ERROR(0);
|
|
|
UV_SUCCESS(handle);
|
|
|
}
|
|
@@ -875,7 +827,7 @@ BC_WRAP7(w_udp_send_ipv6);
|
|
|
|
|
|
CAMLprim value w_udp_recv_start(value handle, value cb) {
|
|
|
CAMLparam2(handle, cb);
|
|
|
- UV_HANDLE_DATA_SUB(Udp_val(handle), udp).cb_read = cb;
|
|
|
+ UV_SET_CB(UV_HANDLE_DATA_SUB(Udp_val(handle), udp).cb_read, cb);
|
|
|
UV_ERROR_CHECK(uv_udp_recv_start(Udp_val(handle), handle_stream_cb_alloc, handle_udp_cb_recv));
|
|
|
UV_SUCCESS_UNIT;
|
|
|
}
|
|
@@ -1061,9 +1013,9 @@ CAMLprim value w_timer_start(value loop, value timeout, value cb) {
|
|
|
CAMLparam3(loop, timeout, cb);
|
|
|
UV_ALLOC_CHECK(handle, uv_timer_t);
|
|
|
UV_ERROR_CHECK_C(uv_timer_init(Loop_val(loop), Timer_val(handle)), free(Timer_val(handle)));
|
|
|
- UV_HANDLE_DATA(Timer_val(handle)) = alloc_data_timer(cb);
|
|
|
- if (UV_HANDLE_DATA(Timer_val(handle)) == NULL)
|
|
|
+ if ((UV_HANDLE_DATA(Timer_val(handle)) = alloc_data()) == NULL)
|
|
|
UV_ERROR(0);
|
|
|
+ UV_SET_CB(UV_HANDLE_DATA_SUB(Timer_val(handle), timer).cb_timer, cb);
|
|
|
UV_ERROR_CHECK_C(
|
|
|
uv_timer_start(Timer_val(handle), handle_timer_cb, Int_val(timeout), Int_val(timeout)),
|
|
|
{ unalloc_data(UV_HANDLE_DATA(Timer_val(handle))); free(Timer_val(handle)); }
|
|
@@ -1077,7 +1029,7 @@ CAMLprim value w_timer_stop(value handle, value cb) {
|
|
|
uv_timer_stop(Timer_val(handle)),
|
|
|
{ unalloc_data(UV_HANDLE_DATA(Timer_val(handle))); free(Timer_val(handle)); }
|
|
|
);
|
|
|
- ((uv_w_handle_t *)UV_HANDLE_DATA(Timer_val(handle)))->cb_close = cb;
|
|
|
+ UV_SET_CB(((uv_w_handle_t *)UV_HANDLE_DATA(Timer_val(handle)))->cb_close, cb);
|
|
|
uv_close(Handle_val(handle), handle_close_cb);
|
|
|
UV_SUCCESS_UNIT;
|
|
|
}
|
|
@@ -1101,9 +1053,9 @@ CAMLprim value w_spawn(value loop, value cb, value file, value args, value env,
|
|
|
CAMLparam5(loop, cb, file, args, env);
|
|
|
CAMLxparam5(cwd, flags, stdio, uid, gid);
|
|
|
UV_ALLOC_CHECK(handle, uv_process_t);
|
|
|
- UV_HANDLE_DATA(Process_val(handle)) = alloc_data_process(cb);
|
|
|
- if (UV_HANDLE_DATA(Process_val(handle)) == NULL)
|
|
|
+ if ((UV_HANDLE_DATA(Process_val(handle)) = alloc_data()) == NULL)
|
|
|
UV_ERROR(0);
|
|
|
+ UV_SET_CB(UV_HANDLE_DATA_SUB(Process_val(handle), process).cb_exit, cb);
|
|
|
char **args_u = malloc(sizeof(char *) * (Wosize_val(args) + 1));
|
|
|
for (int i = 0; i < Wosize_val(args); i++)
|
|
|
args_u[i] = strdup(String_val(Field(args, i)));
|
|
@@ -1183,8 +1135,7 @@ CAMLprim value w_pipe_init(value loop, value ipc) {
|
|
|
CAMLparam2(loop, ipc);
|
|
|
UV_ALLOC_CHECK(handle, uv_pipe_t);
|
|
|
UV_ERROR_CHECK_C(uv_pipe_init(Loop_val(loop), Pipe_val(handle), Bool_val(ipc)), free(Pipe_val(handle)));
|
|
|
- UV_HANDLE_DATA(Pipe_val(handle)) = alloc_data_pipe();
|
|
|
- if (UV_HANDLE_DATA(Pipe_val(handle)) == NULL)
|
|
|
+ if ((UV_HANDLE_DATA(Pipe_val(handle)) = alloc_data()) == NULL)
|
|
|
UV_ERROR(0);
|
|
|
UV_SUCCESS(handle);
|
|
|
}
|
|
@@ -1199,8 +1150,7 @@ CAMLprim value w_pipe_accept(value loop, value server) {
|
|
|
CAMLparam2(loop, server);
|
|
|
UV_ALLOC_CHECK(client, uv_pipe_t);
|
|
|
UV_ERROR_CHECK_C(uv_pipe_init(Loop_val(loop), Pipe_val(client), 0), free(Pipe_val(client)));
|
|
|
- UV_HANDLE_DATA(Pipe_val(client)) = alloc_data_pipe();
|
|
|
- if (UV_HANDLE_DATA(Pipe_val(client)) == NULL)
|
|
|
+ if ((UV_HANDLE_DATA(Pipe_val(client)) = alloc_data()) == NULL)
|
|
|
UV_ERROR(0);
|
|
|
UV_ERROR_CHECK_C(uv_accept(Stream_val(server), Stream_val(client)), free(Pipe_val(client)));
|
|
|
UV_SUCCESS(client);
|
|
@@ -1232,8 +1182,7 @@ CAMLprim value w_pipe_accept_pending(value loop, value handle) {
|
|
|
ret = caml_alloc(1, 0);
|
|
|
UV_ALLOC_CHECK(client, uv_pipe_t);
|
|
|
UV_ERROR_CHECK_C(uv_pipe_init(Loop_val(loop), Pipe_val(client), 0), free(Pipe_val(client)));
|
|
|
- UV_HANDLE_DATA(Pipe_val(client)) = alloc_data_pipe();
|
|
|
- if (UV_HANDLE_DATA(Pipe_val(client)) == NULL)
|
|
|
+ if ((UV_HANDLE_DATA(Pipe_val(client)) = alloc_data()) == NULL)
|
|
|
UV_ERROR(0);
|
|
|
UV_ERROR_CHECK_C(uv_accept(Stream_val(handle), Stream_val(client)), free(Pipe_val(client)));
|
|
|
Store_field(ret, 0, client);
|
|
@@ -1242,8 +1191,7 @@ CAMLprim value w_pipe_accept_pending(value loop, value handle) {
|
|
|
ret = caml_alloc(1, 1);
|
|
|
UV_ALLOC_CHECK(client, uv_tcp_t);
|
|
|
UV_ERROR_CHECK_C(uv_tcp_init(Loop_val(loop), Tcp_val(client)), free(Tcp_val(client)));
|
|
|
- UV_HANDLE_DATA(Tcp_val(client)) = alloc_data_tcp(Val_unit, Val_unit);
|
|
|
- if (UV_HANDLE_DATA(Tcp_val(client)) == NULL)
|
|
|
+ if ((UV_HANDLE_DATA(Tcp_val(client)) = alloc_data()) == NULL)
|
|
|
UV_ERROR(0);
|
|
|
UV_ERROR_CHECK_C(uv_accept(Stream_val(handle), Stream_val(client)), free(Tcp_val(client)));
|
|
|
Store_field(ret, 0, client);
|