Skip to content
Closed
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
61 changes: 45 additions & 16 deletions lib/polly.ml
Original file line number Diff line number Diff line change
Expand Up @@ -96,43 +96,72 @@ module Events = struct
let test x y = x land y <> empty
end

type t = Unix.file_descr (* epoll fd *)

external caml_polly_add : t -> Unix.file_descr -> Events.t -> unit
= "caml_polly_add"

external caml_polly_del : t -> Unix.file_descr -> Events.t -> unit
= "caml_polly_del"

external caml_polly_mod : t -> Unix.file_descr -> Events.t -> unit
= "caml_polly_mod"
type t = int (* epoll fd *)

external caml_polly_add :
( (t[@untagged])
-> (int[@untagged])
-> (Events.t[@untagged])
-> (int[@untagged])
[@noalloc]
) = "caml_polly_add" "caml_untagged_polly_add"

external caml_polly_del :
( (t[@untagged])
-> (int[@untagged])
-> (Events.t[@untagged])
-> (int[@untagged])
[@noalloc]
) = "caml_polly_del" "caml_untagged_polly_del"

external caml_polly_mod :
( (t[@untagged])
-> (int[@untagged])
-> (Events.t[@untagged])
-> (int[@untagged])
[@noalloc]
) = "caml_polly_mod" "caml_untagged_polly_mod"

external caml_polly_create1 : unit -> t = "caml_polly_create1"

external caml_polly_wait :
t (* epoll fd *)
-> int (* max number of fds handled *)
-> int (* timeout in ms *)
-> (Unix.file_descr -> Unix.file_descr -> Events.t -> unit)
-> (t -> Unix.file_descr -> Events.t -> unit)
-> int (* actual number of ready fds; 0 = timeout *) = "caml_polly_wait"

external caml_polly_wait_fold :
t (* epoll fd *)
-> int (* max number of fds handled *)
-> int (* timeout in ms *)
-> 'a (* initial value *)
-> (Unix.file_descr -> Unix.file_descr -> Events.t -> 'a -> 'a)
-> (t -> Unix.file_descr -> Events.t -> 'a -> 'a)
-> 'a (* final value *) = "caml_polly_wait_fold"

let create = caml_polly_create1

let close t = Unix.close t
let close t = Unix.close (Obj.magic t : Unix.file_descr)

external uerror : string -> 'a = "caml_raise_unix_error"

let add = caml_polly_add
let add : t -> Unix.file_descr -> Events.t -> unit =
fun t fd evt ->
let __FUNCTION__ = "Polly.add" in
let r = caml_polly_add t (Obj.magic fd) evt in
if r = -1 then uerror __FUNCTION__

let del t fd = caml_polly_del t fd Events.empty
let del : t -> Unix.file_descr -> unit =
fun t fd ->
let __FUNCTION__ = "Polly.del" in
let r = caml_polly_del t (Obj.magic fd) Events.empty in
if r = -1 then uerror __FUNCTION__

let upd = caml_polly_mod
let upd : t -> Unix.file_descr -> Events.t -> unit =
fun t fd evt ->
let __FUNCTION__ = "Polly.upd" in
let r = caml_polly_mod t (Obj.magic fd) evt in
if r = -1 then uerror __FUNCTION__

let wait = caml_polly_wait

Expand Down
46 changes: 37 additions & 9 deletions lib/polly_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ CONSTANT(EPOLLET);
CONSTANT(EPOLLEXCLUSIVE);
#endif

/* necessary because of changes from 4.X to 5.X in ocaml,
uerror is a macro in 5.0 */
CAMLprim void caml_raise_unix_error(value funname) {
CAMLparam1(funname);
uerror(String_val(funname),Nothing);
}

CAMLprim value caml_polly_create1(value val_unit)
{
CAMLparam1(val_unit);
Expand All @@ -60,33 +67,54 @@ CAMLprim value caml_polly_create1(value val_unit)
static value
caml_polly_ctl(value val_epfd, value val_fd, value val_events, int op)
{
CAMLparam3(val_epfd, val_fd, val_events);
struct epoll_event event = {
.events = (uint32_t) Int_val(val_events),
.data.fd = Int_val(val_fd)
};
CAMLparam0(); /* no need to register int */
struct epoll_event event = {
.events = (uint32_t) Int_val(val_events),
.data.fd = Int_val(val_fd)
};

if (epoll_ctl(Int_val(val_epfd), op, Int_val(val_fd), &event) == -1)
uerror(__FUNCTION__, Nothing);

CAMLreturn(Val_unit);
CAMLreturn(Val_int(epoll_ctl(Int_val(val_epfd), op, Int_val(val_fd), &event)));
}

CAMLprim value caml_polly_add(value val_epfd, value val_fd, value val_events)
{
return caml_polly_ctl(val_epfd, val_fd, val_events, EPOLL_CTL_ADD);
}

int caml_untagged_polly_add(int epfd, int fd, int events) {
struct epoll_event event = {
.events = (uint32_t) events,
.data.fd = fd
};
return epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event);
}

CAMLprim value caml_polly_mod(value val_epfd, value val_fd, value val_events)
{
return caml_polly_ctl(val_epfd, val_fd, val_events, EPOLL_CTL_MOD);
}

int caml_untagged_polly_mod(int epfd, int fd, int events) {
struct epoll_event event = {
.events = (uint32_t) events,
.data.fd = fd
};
return epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &event);
}

CAMLprim value caml_polly_del(value val_epfd, value val_fd, value val_events)
{
return caml_polly_ctl(val_epfd, val_fd, val_events, EPOLL_CTL_DEL);
}

int caml_untagged_polly_del(int epfd, int fd, int events) {
struct epoll_event event = {
.events = (uint32_t) events,
.data.fd = fd
};
return epoll_ctl(epfd, EPOLL_CTL_DEL, fd, &event);
}

CAMLprim value
caml_polly_wait(value val_epfd, value val_max, value val_timeout, value val_f)
{
Expand Down