package uwt

  1. Overview
  2. Docs
type t
include module type of Stream with type t := 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
val to_handle : t -> Handle.t
val is_readable : t -> bool
val is_writable : t -> bool
val read_start : t -> cb:(Stdlib.Bytes.t uv_result -> unit) -> Int_result.unit
val read_start_exn : t -> cb:(Stdlib.Bytes.t uv_result -> unit) -> unit
val read_stop : t -> Int_result.unit
val read_stop_exn : t -> unit
val read : ?pos:int -> ?len:int -> t -> buf:bytes -> int Lwt.t

There is currently no uv_read function in libuv, just read_start and * read_stop. * This is a wrapper for your convenience. It calls read_stop internally, if * you don't continue with reading immediately. Zero result indicates EOF. * * There are currently plans to add uv_read and uv_try_read to libuv * itself. If these changes got merged, Stream.read will wrap them - * even if there will be small semantic differences.

val read_ba : ?pos:int -> ?len:int -> t -> buf:buf -> int Lwt.t
val write_queue_size : t -> int
val try_write : ?pos:int -> ?len:int -> t -> buf:bytes -> Int_result.int
val try_write_ba : ?pos:int -> ?len:int -> t -> buf:buf -> Int_result.int
val try_write_string : ?pos:int -> ?len:int -> t -> buf:string -> Int_result.int
val write : ?pos:int -> ?len:int -> t -> buf:bytes -> unit Lwt.t
val write_string : ?pos:int -> ?len:int -> t -> buf:string -> unit Lwt.t
val write_ba : ?pos:int -> ?len:int -> t -> buf:buf -> unit Lwt.t
val write_raw : ?pos:int -> ?len:int -> t -> buf:bytes -> unit Lwt.t

write is eager. If len is not very large, it first calls try_write internally to check if it can return immediately (without the overhead of creating a sleeping thread and waking it up later). If it can't write everything instantly, it will call write_raw internally. write_raw is exposed here mainly in order to write unit tests for it. But you can also use it, if you your buf is very large or you know for another reason, that try_write will fail.

val write_raw_string : ?pos:int -> ?len:int -> t -> buf:string -> unit Lwt.t
val write_raw_ba : ?pos:int -> ?len:int -> t -> buf:buf -> unit Lwt.t
val write2 : ?pos:int -> ?len:int -> buf:bytes -> send:t -> t -> unit Lwt.t
val write2_ba : ?pos:int -> ?len:int -> buf:buf -> send:t -> t -> unit Lwt.t
val write2_string : ?pos:int -> ?len:int -> buf:string -> send:t -> t -> unit Lwt.t
val listen : t -> max:int -> cb:(t -> Int_result.unit -> unit) -> Int_result.unit
val listen_exn : t -> max:int -> cb:(t -> Int_result.unit -> unit) -> unit
val accept_raw : server:t -> client:t -> Int_result.unit
val accept_raw_exn : server:t -> client:t -> unit
val shutdown : t -> unit Lwt.t
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_stream : t -> Stream.t
val init : unit -> t

See comment to Pipe.init

val init_ipv4 : unit -> t uv_result

wrappers around uv_tcp_init_ex

val init_ipv4_exn : unit -> t
val init_ipv6 : unit -> t uv_result
val init_ipv6_exn : unit -> t
type mode =
  1. | Ipv6_only
val opentcp : Unix.file_descr -> t uv_result

See comment to Pipe.openpipe

val opentcp_exn : Unix.file_descr -> t
val bind : ?mode:mode list -> t -> addr:sockaddr -> unit -> Int_result.unit
  • parameter mode:

    default is the empty list

val bind_exn : ?mode:mode list -> t -> addr:sockaddr -> unit -> unit
val nodelay : t -> bool -> Int_result.unit
val nodelay_exn : t -> bool -> unit
val keepalive : t -> bool -> Int_result.unit
val keepalive_exn : t -> bool -> unit
val simultaneous_accepts : t -> bool -> Int_result.unit
val simultaneous_accepts_exn : t -> bool -> unit
val getsockname : t -> sockaddr uv_result
val getsockname_exn : t -> sockaddr
val getpeername : t -> sockaddr uv_result
val getpeername_exn : t -> sockaddr
val connect : t -> addr:sockaddr -> unit Lwt.t
val accept : t -> t uv_result

initializes a new client and calls accept_raw with it

val accept_exn : t -> t
val with_tcp : (t -> 'a Lwt.t) -> 'a Lwt.t

See comments to Pipe.with_pipe

val with_connect : addr:sockaddr -> (t -> 'a Lwt.t) -> 'a Lwt.t
val with_open : Unix.file_descr -> (t -> 'a Lwt.t) -> 'a Lwt.t
val with_accept : t -> (t -> 'a Lwt.t) -> 'a Lwt.t
OCaml

Innovation. Community. Security.