]> xenbits.xensource.com Git - people/jgross/xen.git/commitdiff
tools/ocaml/xenstored: drop select based socket watching
authorEdwin Török <edvin.torok@citrix.com>
Mon, 17 Aug 2020 18:45:47 +0000 (19:45 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 18 Aug 2020 16:34:50 +0000 (17:34 +0100)
Poll has been the default since 2014, I think we can safely say by now
that poll() works and we don't need to fall back to select().

This will allow fixing up the way we call poll to be more efficient
(and pave the way for introducing epoll support):
currently poll wraps the select API, which is inefficient.

Signed-off-by: Edwin Török <edvin.torok@citrix.com>
Acked-by: Christian Lindig <christian.lindig@citrix.com>
tools/ocaml/xenstored/Makefile
tools/ocaml/xenstored/parse_arg.ml
tools/ocaml/xenstored/poll.ml [new file with mode: 0644]
tools/ocaml/xenstored/poll.mli [new file with mode: 0644]
tools/ocaml/xenstored/select.ml [deleted file]
tools/ocaml/xenstored/select.mli [deleted file]
tools/ocaml/xenstored/xenstored.ml

index 68d35c483ad0404d4b6816f79b5421569e83906b..692a62584e88843697fe085d7714f87df21f4603 100644 (file)
@@ -18,12 +18,12 @@ OCAMLINCLUDE += \
        -I $(OCAML_TOPLEVEL)/libs/xc \
        -I $(OCAML_TOPLEVEL)/libs/eventchn
 
-LIBS = syslog.cma syslog.cmxa select.cma select.cmxa
+LIBS = syslog.cma syslog.cmxa poll.cma poll.cmxa
 syslog_OBJS = syslog
 syslog_C_OBJS = syslog_stubs
-select_OBJS = select
-select_C_OBJS = select_stubs
-OCAML_LIBRARY = syslog select
+poll_OBJS = poll
+poll_C_OBJS = select_stubs
+OCAML_LIBRARY = syslog poll
 
 LIBS += systemd.cma systemd.cmxa
 systemd_OBJS = systemd
@@ -58,13 +58,13 @@ OBJS = paths \
        process \
        xenstored
 
-INTF = symbol.cmi trie.cmi syslog.cmi systemd.cmi select.cmi
+INTF = symbol.cmi trie.cmi syslog.cmi systemd.cmi poll.cmi
 
 XENSTOREDLIBS = \
        unix.cmxa \
        -ccopt -L -ccopt . syslog.cmxa \
        -ccopt -L -ccopt . systemd.cmxa \
-       -ccopt -L -ccopt . select.cmxa \
+       -ccopt -L -ccopt . poll.cmxa \
        -ccopt -L -ccopt $(OCAML_TOPLEVEL)/libs/mmap $(OCAML_TOPLEVEL)/libs/mmap/xenmmap.cmxa \
        -ccopt -L -ccopt $(OCAML_TOPLEVEL)/libs/eventchn $(OCAML_TOPLEVEL)/libs/eventchn/xeneventchn.cmxa \
        -ccopt -L -ccopt $(OCAML_TOPLEVEL)/libs/xc $(OCAML_TOPLEVEL)/libs/xc/xenctrl.cmxa \
index 1803c3eda0c8f99fc6510355e166ae69e3bab13e..2c4b5a8528532b2d5a20c4232c530ef474df3057 100644 (file)
@@ -25,7 +25,6 @@ type config =
        tracefile: string option; (* old xenstored compatibility *)
        restart: bool;
        disable_socket: bool;
-       use_select: bool;
 }
 
 let do_argv =
@@ -37,7 +36,7 @@ let do_argv =
        and config_file = ref ""
        and restart = ref false
        and disable_socket = ref false
-       and use_select = ref false in
+       in
 
        let speclist =
                [ ("--no-domain-init", Arg.Unit (fun () -> domain_init := false),
@@ -54,9 +53,8 @@ let do_argv =
                  ("-T", Arg.Set_string tracefile, ""); (* for compatibility *)
                  ("--restart", Arg.Set restart, "Read database on starting");
                  ("--disable-socket", Arg.Unit (fun () -> disable_socket := true), "Disable socket");
-                 ("--use-select", Arg.Unit (fun () -> use_select := true), "Use select instead of poll"); (* for backward compatibility and testing *)
                ] in
-       let usage_msg = "usage : xenstored [--config-file <filename>] [--no-domain-init] [--help] [--no-fork] [--reraise-top-level] [--restart] [--disable-socket] [--use-select]" in
+       let usage_msg = "usage : xenstored [--config-file <filename>] [--no-domain-init] [--help] [--no-fork] [--reraise-top-level] [--restart] [--disable-socket]" in
        Arg.parse speclist (fun _ -> ()) usage_msg;
        {
                domain_init = !domain_init;
@@ -68,5 +66,4 @@ let do_argv =
                tracefile = if !tracefile <> "" then Some !tracefile else None;
                restart = !restart;
                disable_socket = !disable_socket;
-               use_select = !use_select;
        }
diff --git a/tools/ocaml/xenstored/poll.ml b/tools/ocaml/xenstored/poll.ml
new file mode 100644 (file)
index 0000000..26f8620
--- /dev/null
@@ -0,0 +1,67 @@
+(*
+ * Copyright (C) 2014 Zheng Li <dev@zheng.li>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *)
+
+
+(* The [read], [write], [except] are fields mapped to the POLLIN/OUT/PRI
+   subscription flags used by poll, which have a correspondence to the
+   readfds, writefds, exceptfds concept as in select. *)
+type event = {
+       mutable read: bool;
+       mutable write: bool;
+       mutable except: bool;
+}
+
+external select_on_poll: (Unix.file_descr * event) array -> int -> int = "stub_select_on_poll"
+external set_fd_limit: int -> unit = "stub_set_fd_limit"
+
+(* The rlim_max given to setrlimit must not go above the system level nr_open,
+   which we can read from /proc/sys. *)
+let get_sys_fs_nr_open () =
+       try
+               let ch = open_in "/proc/sys/fs/nr_open" in
+               let v = int_of_string (input_line ch) in
+               close_in_noerr ch; v
+       with _ -> 1024 * 1024
+
+let init_event () = {read = false; write = false; except = false}
+
+let poll_select in_fds out_fds exc_fds timeout =
+       let h = Hashtbl.create 57 in
+       let add_event event_set fd =
+               let e =
+                       try Hashtbl.find h fd
+                       with Not_found ->
+                               let e = init_event () in
+                               Hashtbl.add h fd e; e in
+               event_set e in
+       List.iter (add_event (fun x -> x.read <- true)) in_fds;
+       List.iter (add_event (fun x -> x.write <- true)) out_fds;
+       List.iter (add_event (fun x -> x.except <- true)) exc_fds;
+       (* Unix.stdin and init_event are dummy input as stubs, which will
+           always be overwritten later on.  *)
+       let a = Array.make (Hashtbl.length h) (Unix.stdin, init_event ()) in
+       let i = ref (-1) in
+       Hashtbl.iter (fun fd event -> incr i; Array.set a !i (fd, event)) h;
+       let n = select_on_poll a (int_of_float (timeout *. 1000.)) in
+       let r = [], [], [] in
+       if n = 0 then r else
+               Array.fold_right
+                       (fun (fd, event) (r, w, x) ->
+                        (if event.read then fd :: r else r),
+                        (if event.write then fd :: w else w),
+                        (if event.except then fd :: x else x))
+                       a r
+
+let () =
+        set_fd_limit (get_sys_fs_nr_open ())
diff --git a/tools/ocaml/xenstored/poll.mli b/tools/ocaml/xenstored/poll.mli
new file mode 100644 (file)
index 0000000..f73465b
--- /dev/null
@@ -0,0 +1,19 @@
+(*
+ * Copyright (C) 2014 Zheng Li <dev@zheng.li>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *)
+
+
+(** Same interface and semantics as [Unix.select], implemented using poll(3). *)
+val poll_select:
+       Unix.file_descr list -> Unix.file_descr list -> Unix.file_descr list -> float
+       -> Unix.file_descr list * Unix.file_descr list * Unix.file_descr list
diff --git a/tools/ocaml/xenstored/select.ml b/tools/ocaml/xenstored/select.ml
deleted file mode 100644 (file)
index 0455e16..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-(*
- * Copyright (C) 2014 Zheng Li <dev@zheng.li>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; version 2.1 only. with the special
- * exception on linking described in file LICENSE.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *)
-
-
-(* The [read], [write], [except] are fields mapped to the POLLIN/OUT/PRI
-   subscription flags used by poll, which have a correspondence to the
-   readfds, writefds, exceptfds concept as in select. *)
-type event = {
-       mutable read: bool;
-       mutable write: bool;
-       mutable except: bool;
-}
-
-external select_on_poll: (Unix.file_descr * event) array -> int -> int = "stub_select_on_poll"
-external set_fd_limit: int -> unit = "stub_set_fd_limit"
-
-(* The rlim_max given to setrlimit must not go above the system level nr_open,
-   which we can read from /proc/sys. *)
-let get_sys_fs_nr_open () =
-       try
-               let ch = open_in "/proc/sys/fs/nr_open" in
-               let v = int_of_string (input_line ch) in
-               close_in_noerr ch; v
-       with _ -> 1024 * 1024
-
-let init_event () = {read = false; write = false; except = false}
-
-let poll_select in_fds out_fds exc_fds timeout =
-       let h = Hashtbl.create 57 in
-       let add_event event_set fd =
-               let e =
-                       try Hashtbl.find h fd
-                       with Not_found ->
-                               let e = init_event () in
-                               Hashtbl.add h fd e; e in
-               event_set e in
-       List.iter (add_event (fun x -> x.read <- true)) in_fds;
-       List.iter (add_event (fun x -> x.write <- true)) out_fds;
-       List.iter (add_event (fun x -> x.except <- true)) exc_fds;
-       (* Unix.stdin and init_event are dummy input as stubs, which will
-           always be overwritten later on.  *)
-       let a = Array.make (Hashtbl.length h) (Unix.stdin, init_event ()) in
-       let i = ref (-1) in
-       Hashtbl.iter (fun fd event -> incr i; Array.set a !i (fd, event)) h;
-       let n = select_on_poll a (int_of_float (timeout *. 1000.)) in
-       let r = [], [], [] in
-       if n = 0 then r else
-               Array.fold_right
-                       (fun (fd, event) (r, w, x) ->
-                        (if event.read then fd :: r else r),
-                        (if event.write then fd :: w else w),
-                        (if event.except then fd :: x else x))
-                       a r
-
-(* If the use_poll function is not called at all, we default to the original Unix.select behavior *)
-let select_fun = ref Unix.select
-
-let use_poll yes =
-       let sel_fun, max_fd =
-               if yes then poll_select, get_sys_fs_nr_open ()
-               else Unix.select, 1024 in
-       select_fun := sel_fun;
-       set_fd_limit max_fd
-
-let select in_fds out_fds exc_fds timeout =
-       (!select_fun) in_fds out_fds exc_fds timeout
diff --git a/tools/ocaml/xenstored/select.mli b/tools/ocaml/xenstored/select.mli
deleted file mode 100644 (file)
index 3912779..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-(*
- * Copyright (C) 2014 Zheng Li <dev@zheng.li>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; version 2.1 only. with the special
- * exception on linking described in file LICENSE.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *)
-
-
-(** Same interface and semantics as [Unix.select] but with an extra alternative
-    implementation based on poll. Switching implementations is done by calling
-     the [use_poll] function. *)
-val select:
-       Unix.file_descr list -> Unix.file_descr list -> Unix.file_descr list -> float
-       -> Unix.file_descr list * Unix.file_descr list * Unix.file_descr list
-
-(** [use_poll true] will use poll based select with max fds number limitation
-   eliminated; [use_poll false] will use standard [Unix.select] with max fd
-   number set to 1024; not calling this function at all equals to use the
-   standard [Unix.select] with max fd number setting untouched. *)
-val use_poll: bool -> unit
index a4466c5b5ca9d955564e29128ec6c62367a1476a..5b96f1852a916058ec7f6d2daedbf06b613f893f 100644 (file)
@@ -308,8 +308,6 @@ let _ =
                );
        );
 
-       Select.use_poll (not cf.use_select);
-
        Sys.set_signal Sys.sighup (Sys.Signal_handle sighup_handler);
        Sys.set_signal Sys.sigterm (Sys.Signal_handle (fun _ -> quit := true));
        Sys.set_signal Sys.sigusr1 (Sys.Signal_handle (fun _ -> sigusr1_handler store));
@@ -453,7 +451,7 @@ let _ =
                let inset, outset = Connections.select ~only_if:is_peaceful cons in
                let rset, wset, _ =
                try
-                       Select.select (spec_fds @ inset) outset [] timeout
+                       Poll.poll_select (spec_fds @ inset) outset [] timeout
                with Unix.Unix_error(Unix.EINTR, _, _) ->
                        [], [], [] in
                let sfds, cfds =