Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,9 @@ with the same meaning as the return code from the corresponding system call (`op

```ocaml
# let fd =
if result < 0 then failwith ("Error: " ^ string_of_int result);
(Obj.magic result : Unix.file_descr);;
match Uring.file_descr_of_result result with
| Error errno -> failwith ("Error: " ^ Unix.error_message errno)
| Ok fd -> fd;;
val fd : Unix.file_descr = <abstr>
```

Expand Down
3 changes: 3 additions & 0 deletions lib/uring/uring.ml
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ module Uring = struct
external wait_cqe : t -> cqe_option = "ocaml_uring_wait_cqe"
external wait_cqe_timeout : float -> t -> cqe_option = "ocaml_uring_wait_cqe_timeout"
external peek_cqe : t -> cqe_option = "ocaml_uring_peek_cqe"
external file_descr_of_result : int -> (Unix.file_descr, Unix.error) result = "ocaml_uring_file_descr_of_result"

external error_of_errno : int -> Unix.error = "ocaml_uring_error_of_errno"
external register_eventfd : t -> Unix.file_descr -> unit = "ocaml_uring_register_eventfd"
Expand Down Expand Up @@ -629,6 +630,8 @@ let get_cqe_nonblocking t =

let peek = get_cqe_nonblocking

let file_descr_of_result = Uring.file_descr_of_result

let register_eventfd t fd =
check t;
Uring.register_eventfd t.uring fd
Expand Down
4 changes: 4 additions & 0 deletions lib/uring/uring.mli
Original file line number Diff line number Diff line change
Expand Up @@ -860,6 +860,10 @@ val get_cqe_nonblocking : 'a t -> 'a completion_option
val peek : 'a t -> 'a completion_option
[@@deprecated "Renamed to Uring.get_cqe_nonblocking"]

val file_descr_of_result : int -> (Unix.file_descr, Unix.error) result
(** Converts the result of syscalls which return either a file_descriptor or
-errno to either a file descriptor or a result. *)

val register_eventfd : 'a t -> Unix.file_descr -> unit
(** [register_eventfd t fd] will register an eventfd to the the uring [t].

Expand Down
23 changes: 23 additions & 0 deletions lib/uring/uring_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,29 @@ value ocaml_uring_error_of_errno(value v_errno) {
return unix_error_of_code(Int_val(v_errno));
}

#ifndef CAML_UNIX_FILE_DESCR_API
#ifdef _WIN32
#error "Unix-specific treatment of Unix.file_descr"
#else
#define caml_unix_file_descr_of_fd(fd) Val_int(fd)
#endif /* #ifdef _WIN32 */
#endif /* #ifndef CAML_UNIX_FILE_DESCR_API */

value ocaml_uring_file_descr_of_result(value v_result)
{
CAMLparam0();
CAMLlocal2(result, val);
if (Int_val(v_result) < 0) {
val = unix_error_of_code(-Int_val(v_result));
result = caml_alloc_small(1, 1);
} else {
val = caml_unix_file_descr_of_fd(Int_val(v_result));
result = caml_alloc_small(1, 0);
}
Field(result, 0) = val;
CAMLreturn(result);
}

#define Probe_val(v) (*((struct io_uring_probe **) Data_custom_val(v)))

static void finalize_probe(value v) {
Expand Down
38 changes: 18 additions & 20 deletions tests/main.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ let rec consume t =
| Some { data; result } -> (data, result)
| None -> consume t

let rec consume_fd t =
match Uring.wait ~timeout:1. t with
| None -> consume_fd t
| Some { data; result } ->
match Uring.file_descr_of_result result with
| Ok fd -> data, fd
| Error _ -> assert false

let traceln fmt =
Format.printf (fmt ^^ "@.")
```
Expand Down Expand Up @@ -134,10 +142,7 @@ val t : [ `Open ] Uring.t = <abstr>
# Uring.submit t;;;
- : int = 1

# let token, fd =
let token, fd = consume t in
assert (fd >= 0);
token, (Obj.magic fd : Unix.file_descr);;
# let token, fd = consume_fd t;;
val token : [ `Open ] = `Open
val fd : Unix.file_descr = <abstr>

Expand Down Expand Up @@ -170,10 +175,7 @@ val t : [ `Create ] Uring.t = <abstr>
# Uring.submit t;;
- : int = 1

# let token, fd =
let token, fd = consume t in
assert (fd >= 0);
token, (Obj.magic fd : Unix.file_descr);;
# let token, fd = consume_fd t;;
val token : [ `Create ] = `Create
val fd : Unix.file_descr = <abstr>

Expand Down Expand Up @@ -252,10 +254,7 @@ Now using `~fd`:
# Uring.submit t;;
- : int = 1

# let token, fd =
let token, fd = consume t in
assert (fd >= 0);
token, (Obj.magic fd : Unix.file_descr);;
# let token, fd = consume_fd t;;
val token : [ `Open_path | `Statx ] = `Open_path
val fd : Unix.file_descr = <abstr>

Expand Down Expand Up @@ -301,14 +300,13 @@ val t : [ `Get_path ] Uring.t = <abstr>
path
`Get_path));
traceln "Submitted %d" (Uring.submit t);
let `Get_path, fd = consume t in
if fd >= 0 then (
let fd : Unix.file_descr = Obj.magic fd in
Unix.close fd;
traceln "Opened %S OK" path
) else (
raise (Unix.Unix_error (Uring.error_of_errno fd, "openat2", path))
);;
let `Get_path, result = consume t in
match Uring.file_descr_of_result result with
| Ok fd ->
Unix.close fd;
traceln "Opened %S OK" path
| Error errno ->
raise (Unix.Unix_error (errno, "openat2", path));;
val get : resolve:Uring.Resolve.t -> string -> unit = <fun>

# get ~resolve:Uring.Resolve.empty ".";;
Expand Down