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:(Bytes.t result -> unit) -> Int_result.unit
val read_start_exn : t -> cb:(Bytes.t 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_fileno with type t := t
val fileno : t -> Unix.file_descr 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 : file -> read:bool -> t result
val init_exn : file -> read:bool -> t
type mode =
  1. | Normal
  2. | Raw
  3. | Io
val set_mode : t -> mode:mode -> Int_result.unit
val set_mode_exn : t -> mode:mode -> unit
val reset_mode : unit -> Int_result.unit
val reset_mode_exn : unit -> unit
type winsize = {
  1. width : int;
  2. height : int;
}
val get_winsize : t -> winsize result
val get_winsize_exn : t -> winsize
OCaml

Innovation. Community. Security.