Skip to content

Commit

Permalink
add wrappers for uv_tcp_init_ex and uv_udp_init_ex
Browse files Browse the repository at this point in the history
  • Loading branch information
fdopen committed Jun 29, 2016
1 parent 889e904 commit ea7ca49
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ AC_MSG_CHECKING([posix source 200809L])
AC_CHECK_HEADERS(errno.h stdint.h unistd.h errno.h limits.h sys/stat.h sys/types.h sys/socket.h fcntl.h netinet/in.h netdb.h grp.h pwd.h sys/param.h byteswap.h sys/byteswap.h sys/endian.h)
AC_CHECK_FUNCS(strdup)
AC_CHECK_DECLS([strnlen], [], [], [#include <string.h>])
AC_CHECK_DECLS([uv_os_homedir,uv_os_tmpdir,uv_os_get_passwd,UV_DISCONNECT,UV_TTY_MODE_NORMAL,UV_TTY_MODE_RAW,UV_TTY_MODE_IO],[],[],[#include <uv.h>])
AC_CHECK_DECLS([uv_tcp_init_ex,uv_udp_init_ex,uv_os_homedir,uv_os_tmpdir,uv_os_get_passwd,UV_DISCONNECT,UV_TTY_MODE_NORMAL,UV_TTY_MODE_RAW,UV_TTY_MODE_IO],[],[],[#include <uv.h>])
AC_CHECK_DECLS([uv_fs_realpath],[AC_SUBST(HAVE_UV_REALPATH,1)],[AC_SUBST(HAVE_UV_REALPATH,0)],[#include <uv.h>])

AC_HEADER_STDBOOL
Expand Down
16 changes: 16 additions & 0 deletions src/uwt.ml
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,10 @@ module Tty = struct
let get_winsize_exn t = get_winsize t |> to_exn "tty_get_winsize"
end

type ipv_x =
| PF_INET
| PF_INET6

module Tcp = struct
type t = u
include (Stream: (module type of Stream) with type t := t )
Expand All @@ -599,6 +603,12 @@ module Tcp = struct
| Error ENOMEM -> raise Out_of_memory
| Error x -> eraise "tcp_init" x

external init_ex: loop -> ipv_x -> t uv_result = "uwt_tcp_init_ex"
let init_ipv4 () = init_ex loop PF_INET
let init_ipv4_exn () = init_ex loop PF_INET |> to_exn "tcp_init_ipv4"
let init_ipv6 () = init_ex loop PF_INET6
let init_ipv6_exn () = init_ex loop PF_INET6 |> to_exn "tcp_init_ipv6"

external opentcp:
t -> Unix.file_descr -> Int_result.unit = "uwt_tcp_open_na" "noalloc"

Expand Down Expand Up @@ -702,6 +712,12 @@ module Udp = struct
| Error ENOMEM -> raise Out_of_memory
| Error x -> eraise "init_tcp" x

external init_ex: loop -> ipv_x -> t uv_result = "uwt_udp_init_ex"
let init_ipv4 () = init_ex loop PF_INET
let init_ipv4_exn () = init_ex loop PF_INET |> to_exn "udp_init_ipv4"
let init_ipv6 () = init_ex loop PF_INET6
let init_ipv6_exn () = init_ex loop PF_INET6 |> to_exn "udp_init_ipv6"

external openudp: t -> Unix.file_descr -> Int_result.unit = "uwt_udp_open_na" "noalloc"
let openudp s =
let x = init_raw loop in
Expand Down
12 changes: 12 additions & 0 deletions src/uwt.mli
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,12 @@ module Tcp : sig
(** See comment to {!Pipe.init} *)
val init : unit -> t

(** wrappers around uv_tcp_init_ex *)
val init_ipv4 : unit -> t uv_result
val init_ipv4_exn : unit -> t
val init_ipv6 : unit -> t uv_result
val init_ipv6_exn : unit -> t

type mode =
| Ipv6_only

Expand Down Expand Up @@ -432,6 +438,12 @@ module Udp : sig
(** See comment to {!Pipe.init} *)
val init : unit -> t

(** wrappers around uv_udp_init_ex *)
val init_ipv4 : unit -> t uv_result
val init_ipv4_exn: unit -> t
val init_ipv6 : unit -> t uv_result
val init_ipv6_exn : unit -> t

(** See comment to {!Pipe.openpipe} *)
val openudp : Unix.file_descr -> t uv_result
val openudp_exn : Unix.file_descr -> t
Expand Down
85 changes: 73 additions & 12 deletions src/uwt_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3677,7 +3677,7 @@ uwt_pipe_connect(value o_pipe,value o_path,value o_cb)
/* {{{ Tcp start */
#define UDP_TCP_INIT(name,TYPE) \
CAMLprim value \
uwt_ ## name ## _init(value o_loop) \
uwt_ ## name ## _init(value o_loop) \
{ \
INIT_LOOP_WRAP(l,o_loop); \
CAMLparam1(o_loop); \
Expand All @@ -3688,11 +3688,12 @@ uwt_pipe_connect(value o_pipe,value o_path,value o_cb)
value ret = caml_alloc_small(1,Ok_tag); \
Field(ret,0) = v; \
h->close_executed = 0; \
int erg = uv_ ## name ## _init(&l->loop, \
(uv_ ## name ## _t*)h->handle); \
const int erg = uv_ ## name ## _init(&l->loop, \
(uv_ ## name ## _t*)h->handle); \
if ( erg < 0 ){ \
Field(v,1) = 0; \
Field(ret,0) = Val_uwt_error(erg); \
Tag_val(ret) = Error_tag; \
free_mem_uv_handle_t(h); \
free_struct_handle(h); \
} \
Expand All @@ -3703,6 +3704,75 @@ UDP_TCP_INIT(tcp,UV_TCP)
UDP_TCP_INIT(udp,UV_UDP)
#undef UDP_TCP_INIT

ATTR_UNUSED static value
result_eunavail(void)
{
value ret = caml_alloc_small(1,Error_tag);
Field(ret,0) = VAL_UWT_ERROR_UWT_EUNAVAIL;
return ret;
}

#if HAVE_DECL_UV_UDP_INIT_EX || HAVE_DECL_UV_TCP_INIT_EX
#define UDP_TCP_INIT_EX(name,TYPE) \
CAMLprim value \
uwt_ ## name ## _init_ex(value o_loop, value o_mode) \
{ \
INIT_LOOP_WRAP(l,o_loop); \
CAMLparam1(o_loop); \
CAMLlocal1(v); \
v = handle_create(TYPE,l); \
struct handle * h = Handle_val(v); \
h->close_executed = 1; \
value ret = caml_alloc_small(1,Ok_tag); \
Field(ret,0) = v; \
h->close_executed = 0; \
h->initialized = 1; \
const int mode = Long_val(o_mode) == 0 ? AF_INET : AF_INET6 ; \
const int erg = uv_ ## name ## _init_ex(&l->loop, \
(uv_ ## name ## _t*)h->handle, \
mode ); \
if ( erg < 0 ){ \
Field(v,1) = 0; \
Field(ret,0) = Val_uwt_error(erg); \
Tag_val(ret) = Error_tag; \
free_mem_uv_handle_t(h); \
free_struct_handle(h); \
} \
CAMLreturn(ret); \
}
#endif

#if !HAVE_DECL_UV_UDP_INIT_EX || !HAVE_DECL_UV_TCP_INIT_EX
#define UDP_TCP_INIT_EX_NO(name) \
CAMLprim value \
uwt_ ## name ## _init_ex(value a, value b) \
{ \
(void)a; \
(void)b; \
return (result_eunavail()); \
}
#endif

#if HAVE_DECL_UV_TCP_INIT_EX
UDP_TCP_INIT_EX(tcp,UV_TCP)
#else
UDP_TCP_INIT_EX_NO(tcp)
#endif

#if HAVE_DECL_UV_UDP_INIT_EX
UDP_TCP_INIT_EX(udp,UV_UDP)
#else
UDP_TCP_INIT_EX_NO(udp)
#endif

#ifdef UDP_TCP_INIT_EX
#undef UDP_TCP_INIT_EX
#endif

#ifdef UDP_TCP_INIT_EX_NO
#undef UDP_TCP_INIT_EX_NO
#endif

static value
uwt_tcp_udp_open(value o_tcp, value o_fd, bool tcp)
{
Expand Down Expand Up @@ -5122,15 +5192,6 @@ uwt_os_dir(os_dir fdir_func)
}
#endif

#if !HAVE_DECL_UV_OS_HOMEDIR || !HAVE_DECL_UV_OS_TMPDIR || !HAVE_DECL_UV_OS_GET_PASSWD
static value
result_eunavail(void)
{
value ret = caml_alloc_small(1,Error_tag);
Field(ret,0) = VAL_UWT_ERROR_UWT_EUNAVAIL;
return ret;
}
#endif

CAMLprim value
uwt_os_homedir(value unit)
Expand Down
2 changes: 2 additions & 0 deletions src/uwt_stubs.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ P3(uwt_pipe_connect);

P1(uwt_tcp_init);
P1(uwt_udp_init);
P2(uwt_tcp_init_ex);
P2(uwt_udp_init_ex);
P2(uwt_tcp_open_na);
P2(uwt_udp_open_na);
P3(uwt_tcp_bind_na);
Expand Down
18 changes: 16 additions & 2 deletions test/t_tcp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,21 @@ let with_client_c4 f =
let t = with_connect ~addr:Server.sockaddr @@ fun t -> f t in
m_true t

let use_ext = Uwt.Misc.((version ()).minor) >= 7
let with_connect_own ~addr f =
server_init ();
let t =
if use_ext = false then
Uwt.Tcp.init ()
else if Unix.PF_INET6 = (Uwt.Conv.to_unix_sockaddr_exn addr
|> Unix.domain_of_sockaddr) then
Uwt.Tcp.init_ipv6_exn ()
else
Uwt.Tcp.init_ipv4_exn ()
in
Lwt.finalize (fun () -> Uwt.Tcp.connect t ~addr >>= fun () -> f t)
(fun () -> Uwt.Tcp.close_noerr t; Lwt.return_unit)

let with_exit_exception_hook f =
let caught = ref false in
server_init ();
Expand Down Expand Up @@ -216,8 +231,7 @@ let l = [
m_raises (Uwt.EADDRINUSE,"listen","") (l sockaddr));
("write_allot">::
fun ctx ->
let l addr = with_client @@ fun client ->
connect client ~addr >>= fun () ->
let l addr = with_connect_own ~addr @@ fun client ->
let buf_len = 65_536 in
let x = max 1 (multiplicand ctx) in
let buf_cnt = 64 * x in
Expand Down
11 changes: 10 additions & 1 deletion test/t_udp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,17 @@ let start_server_cb addr : bool Lwt.t =
sleeper
) ( fun () -> Uwt.Udp.close_wait server )

let use_ext = Uwt.Misc.((version ()).minor) >= 7
let start_client ~raw ~iter ~length addr =
let client = Uwt.Udp.init () in
let client =
if use_ext = false then
Uwt.Udp.init ()
else if Unix.PF_INET6 = (Uwt.Conv.to_unix_sockaddr_exn addr
|> Unix.domain_of_sockaddr) then
Uwt.Udp.init_ipv6_exn ()
else
Uwt.Udp.init_ipv4_exn ()
in
let buf = rbytes_create length in
let buf_recv = Bytes.create length in
let send = match raw with
Expand Down

0 comments on commit ea7ca49

Please sign in to comment.