]> xenbits.xensource.com Git - xenclient/toolstack.git/commitdiff
add a main monitor thread that control the quit functionality.
authorVincent Hanquez <vincent.hanquez@eu.citrix.com>
Wed, 12 Aug 2009 12:53:33 +0000 (13:53 +0100)
committerVincent Hanquez <vincent.hanquez@eu.citrix.com>
Wed, 12 Aug 2009 12:53:33 +0000 (13:53 +0100)
also add the skeleton for starting a dbus monitor where to receive RPCs.

xenvm/vmstate.ml
xenvm/xenvm.ml

index 9af2ca71f2dd9573ccd8326bdff3eec622d11ea9..1283c2b92f5ad63e4d66dbb40f726be157e54b3f 100644 (file)
@@ -39,8 +39,19 @@ type locks = {
        l_start: Mutex.t;
 }
 
+type monitor_state = {
+       monitor_use_dbus: bool;
+       monitor_use_json: bool;
+       mutable monitor_json_quit: bool;
+       mutable monitor_dbus_quit: bool;
+}
+
 type vm_state = {
        vm_uuid: string;
+       vm_monitors: monitor_state;
+       quit_mutex: Mutex.t;
+       quit_condition: Condition.t;
+       mutable quit_requested: bool;
        mutable vm_config_path: string;
        mutable vm_arch: Domain.domarch;
        mutable vm_domid: int;
@@ -57,6 +68,15 @@ type vm_state = {
 let state_init uuid config_path cfg =
        {
                vm_uuid = uuid;
+               vm_monitors = {
+                       monitor_use_dbus = false;
+                       monitor_use_json = true;
+                       monitor_json_quit = false;
+                       monitor_dbus_quit = false;
+               };
+               quit_mutex = Mutex.create ();
+               quit_condition = Condition.create ();
+               quit_requested = false;
                vm_config_path = config_path;
                vm_arch = if cfg.hvm then Domain.Arch_HVM else Domain.Arch_native;
                vm_domid = (-1);
index 1ec82ba72927b99b69b058e4705a9dbf9be8f4ab..cd4a127d3004fe7029595f18837a76935837c8a9 100644 (file)
@@ -27,6 +27,13 @@ let thread_create f x =
        let (_: Thread.t) = Thread.create f x in
        ()
 
+let notify_quit state =
+       Mutex.lock state.quit_mutex;
+       state.quit_requested <- true;
+       Condition.signal state.quit_condition;
+       Mutex.unlock state.quit_mutex;
+       ()
+
 let string_of_exn exn =
        match exn with
        | Hotplug.Device_timeout dev ->
@@ -393,7 +400,7 @@ let reread_config state path =
        let cfg = Config.of_file state.vm_uuid (fun errors -> ()) path in
        state.vm_next_cfg <- Some cfg
 
-let do_task quit state (task, args) =
+let do_task state (task, args) =
        let optional_arg default f args s =
                try f args s with Tasks.Argument_not_found _ -> default
                in
@@ -405,7 +412,7 @@ let do_task quit state (task, args) =
        (*maybe assert_vmstate task_vmstate_required;*)
        match task with
        | Tasks.Quit ->
-               quit := true; Xenvmlib.Ok
+               notify_quit state; Xenvmlib.Ok
        | Tasks.Help ->
                do_help ();
        | Tasks.Destroy -> with_xcs (fun xc xs -> Vmact.stop_vm xc xs state); Xenvmlib.Ok
@@ -500,18 +507,11 @@ let do_task quit state (task, args) =
                reread_config state path;
                Xenvmlib.Ok
 
-let monitor_rpc socket state =
-       let read_config_noexn state path =
-               try reread_config state path
-               with exn ->
-                       info "receive exception reading config file ignoring: %s"
-                            (string_of_exn exn)
-               in
+let monitor_rpc_json socket state =
        let assert_vmstate expected =
                if expected <> state.vm_lifestate then
                        raise (Vmact.Vm_bad_state (expected, state.vm_lifestate));
                in
-       let quit = ref false in
        let connections = ref [] in
 
        let reply_error con error =
@@ -538,7 +538,7 @@ let monitor_rpc socket state =
                        let reply_id = match rpc.Jsonrpc.request_id with Some id -> id | None -> Json.Int 0L in
                        let reply =
                                try
-                                       let r = do_task quit state (task, params) in
+                                       let r = do_task state (task, params) in
                                        match r with
                                        | Xenvmlib.Ok -> Jsonrpc.response_make_success reply_id Json.Null
                                        | Xenvmlib.Msg msg -> Jsonrpc.response_make_success reply_id (Json.String msg)
@@ -614,10 +614,7 @@ let monitor_rpc socket state =
                )
                in
 
-       Sys.set_signal Sys.sigint (Sys.Signal_handle (fun i -> quit := true));
-       Sys.set_signal Sys.sighup (Sys.Signal_handle (fun i -> read_config_noexn state None));
-
-       while not !quit
+       while not state.vm_monitors.monitor_json_quit
        do
                let has_work = List.fold_left (fun acc con -> acc || con_has_work con) false !connections in
                let timeout = if has_work then 0. else 1. in
@@ -651,6 +648,9 @@ let monitor_rpc socket state =
                )
        )
 
+let monitor_rpc_dbus state =
+       ()
+
 (*
  * Monitor is in charge of 2 things: listen to VM requests, and listen to user queries.
  * - vm requests are: spontaneous shutdown and reboot
@@ -658,7 +658,28 @@ let monitor_rpc socket state =
  *)
 let monitor socket state =
        thread_create monitor_vm state;
-       monitor_rpc socket state
+       if state.vm_monitors.monitor_use_json then
+               thread_create (monitor_rpc_json socket) state;
+       if state.vm_monitors.monitor_use_dbus then
+               thread_create monitor_rpc_dbus state;
+
+       let read_config_noexn state path =
+               try reread_config state path
+               with exn ->
+                       info "receive exception reading config file ignoring: %s"
+                            (string_of_exn exn)
+               in
+
+       Sys.set_signal Sys.sigint (Sys.Signal_handle (fun i -> notify_quit state));
+       Sys.set_signal Sys.sighup (Sys.Signal_handle (fun i -> read_config_noexn state None));
+
+       Mutex.lock state.quit_mutex;
+       while not state.quit_requested do
+               Condition.wait state.quit_condition state.quit_mutex;
+       done;
+       Mutex.unlock state.quit_mutex;
+       Thread.delay 0.5; (* give time for others threads to finish what they are doing .. *)
+       exit 0
 
 (*********
 let do_snapshot .. =