package uwt

  1. Overview
  2. Docs
type t
include module type of Handle with type t := t
val close : t -> Int_result.unit

Handles are closed automatically, if they are not longer referenced from the OCaml heap. Nevertheless, you should nearly always close them with close, because:

  • if they wrap a file descriptor, you will sooner or later run out of file descriptors. The OCaml garbage collector doesn't give any guarantee, when orphaned memory blocks are removed.
  • you might have registered some repeatedly called action (e.g. timeout, read_start,...), that prevent that all references get removed from the OCaml heap.

However, it's safe to write code in this manner:

let s = Uwt.Tcp.init () in
let c = Uwt.Tcp.init () in
Uwt.Tcp.nodelay s false;
Uwt.Tcp.simultaneous_accepts true;
if foobar () then (* no file descriptor yet assigned, no need to worry
                     about exceptions inside foobar,... *)
  Lwt.return_unit (* no need to close *)
else
  ...

If you want - for whatever reason - keep a file descriptor open for the whole lifetime of your process, remember to keep a reference to its handle.

val close_noerr : t -> unit
val close_wait : t -> unit Lwt.t

Prefer close or close_noerr to close_wait. close or close_noerr return immediately (there are no useful error messages, beside perhaps a notice, that you've already closed that handle).

close_wait is only useful, if you intend to wait until all concurrent write and read threads related to this handle are canceled.

val is_active : t -> bool
val ref' : t -> unit
val unref : t -> unit
val has_ref : t -> bool
include module type of Handle_ext with type t := t
val get_send_buffer_size : t -> Int_result.int
val get_send_buffer_size_exn : t -> int
val get_recv_buffer_size : t -> Int_result.int
val get_recv_buffer_size_exn : t -> int
val set_send_buffer_size : t -> int -> Int_result.unit
val set_send_buffer_size_exn : t -> int -> unit
val set_recv_buffer_size : t -> int -> Int_result.unit
val set_recv_buffer_size_exn : t -> int -> unit
include module type of Handle_fileno with type t := t
val fileno : t -> Unix.file_descr uv_result

The usage of fileno is unsafe and strongly discouraged. But it's sometimes necessary, if you need to interact with third parties libraries. Rules:

  • You must still keep your orginal handle around. Otherwise uwt will close the handle ....
  • close the handle always with Handle.close, not Unix.close or any other function
val fileno_exn : t -> Unix.file_descr
val to_handle : t -> Handle.t
val send_queue_size : t -> int
val send_queue_count : t -> int
val init : unit -> t

See comment to Pipe.init

val init_ipv4 : unit -> t uv_result

wrappers around uv_udp_init_ex

val init_ipv4_exn : unit -> t
val init_ipv6 : unit -> t uv_result
val init_ipv6_exn : unit -> t
val openudp : Unix.file_descr -> t uv_result

See comment to Pipe.openpipe

val openudp_exn : Unix.file_descr -> t
type mode =
  1. | Ipv6_only
  2. | Reuse_addr
val bind : ?mode:mode list -> t -> addr:sockaddr -> unit -> Int_result.unit
  • parameter mode

    default mode is the empty list

val bind_exn : ?mode:mode list -> t -> addr:sockaddr -> unit -> unit
val getsockname : t -> sockaddr uv_result
val getsockname_exn : t -> sockaddr
type membership =
  1. | Leave_group
  2. | Join_group
val set_membership : ?interface:string -> t -> multicast:string -> membership -> Int_result.unit
val set_membership_exn : ?interface:string -> t -> multicast:string -> membership -> unit
val set_multicast_loop : t -> bool -> Int_result.unit
val set_multicast_loop_exn : t -> bool -> unit
val set_multicast_ttl : t -> int -> Int_result.unit
val set_multicast_ttl_exn : t -> int -> unit
val set_multicast_interface : t -> string option -> Int_result.unit
val set_multicast_interface_exn : t -> string option -> unit
val set_broadcast : t -> bool -> Int_result.unit
val set_broadcast_exn : t -> bool -> unit
val set_ttl : t -> int -> Int_result.unit
val set_ttl_exn : t -> int -> unit
val send : ?pos:int -> ?len:int -> buf:bytes -> t -> sockaddr -> unit Lwt.t
val send_ba : ?pos:int -> ?len:int -> buf:buf -> t -> sockaddr -> unit Lwt.t
val send_string : ?pos:int -> ?len:int -> buf:string -> t -> sockaddr -> unit Lwt.t
val send_raw : ?pos:int -> ?len:int -> buf:bytes -> t -> sockaddr -> unit Lwt.t

See comment to Stream.write_raw

val send_raw_ba : ?pos:int -> ?len:int -> buf:buf -> t -> sockaddr -> unit Lwt.t
val send_raw_string : ?pos:int -> ?len:int -> buf:string -> t -> sockaddr -> unit Lwt.t
val try_send : ?pos:int -> ?len:int -> buf:bytes -> t -> sockaddr -> Int_result.int
val try_send_ba : ?pos:int -> ?len:int -> buf:buf -> t -> sockaddr -> Int_result.int
val try_send_string : ?pos:int -> ?len:int -> buf:string -> t -> sockaddr -> Int_result.int
type recv_result =
  1. | Data of Stdlib.Bytes.t * sockaddr option
  2. | Partial_data of Stdlib.Bytes.t * sockaddr option
  3. | Empty_from of sockaddr
  4. | Transmission_error of error

The type definition will likely be changed. Don't use fragile pattern matching for it

val recv_start : t -> cb:(recv_result -> unit) -> Int_result.unit
val recv_start_exn : t -> cb:(recv_result -> unit) -> unit
val recv_stop : t -> Int_result.unit
val recv_stop_exn : t -> unit
type recv = {
  1. recv_len : int;
  2. is_partial : bool;
  3. sockaddr : sockaddr option;
}
val recv : ?pos:int -> ?len:int -> buf:bytes -> t -> recv Lwt.t

Wrappers around recv_start and recv_stop for you convenience, no callback soup.

val recv_ba : ?pos:int -> ?len:int -> buf:buf -> t -> recv Lwt.t
OCaml

Innovation. Community. Security.