let xbcon = Xenbus.Xb.open_mmap ~capacity (Domain.get_interface dom) (fun () -> Domain.notify dom) in
let con = Connection.create xbcon (Some dom) in
Hashtbl.add cons.domains (Domain.get_id dom) con;
- match Domain.get_port dom with
- | Some p -> Hashtbl.add cons.ports p con;
- | None -> ()
+ Hashtbl.add cons.ports (Domain.get_local_port dom) con
let select ?(only_if = (fun _ -> true)) cons =
Hashtbl.fold (fun _ con (ins, outs) ->
let con = find_domain cons id in
Hashtbl.remove cons.domains id;
(match Connection.get_domain con with
- | Some d ->
- (match Domain.get_port d with
- | Some p -> Hashtbl.remove cons.ports p
- | None -> ())
+ | Some d -> Hashtbl.remove cons.ports (Domain.get_local_port d)
| None -> ());
del_watches cons con;
Connection.close con
let debug fmt = Logging.debug "domain" fmt
let warn fmt = Logging.warn "domain" fmt
+(* A bound inter-domain event channel port pair. The remote port, and the
+ local port it is bound to. *)
+type port_pair =
+{
+ local: Xeneventchn.t;
+ remote: int;
+}
+
+(* Sentinal port_pair with both set to EVTCHN_INVALID *)
+let invalid_ports =
+{
+ local = Xeneventchn.of_int 0;
+ remote = 0
+}
+
+let string_of_port_pair p =
+ sprintf "(l %d, r %d)" (Xeneventchn.to_int p.local) p.remote
+
type t =
{
id: Xenctrl.domid;
mfn: nativeint;
interface: Xenmmap.mmap_interface;
eventchn: Event.t;
- mutable remote_port: int;
- mutable port: Xeneventchn.t option;
+ mutable ports: port_pair;
mutable bad_client: bool;
mutable io_credit: int; (* the rounds of ring process left to do, default is 0,
usually set to 1 when there is work detected, could
let get_id domain = domain.id
let get_interface d = d.interface
let get_mfn d = d.mfn
-let get_remote_port d = d.remote_port
-let get_port d = d.port
+let get_remote_port d = d.ports.remote
+let get_local_port d = d.ports.local
let is_bad_domain domain = domain.bad_client
let mark_as_bad domain = domain.bad_client <- true
let is_free_to_conflict = is_dom0
-let string_of_port = function
- | None -> "None"
- | Some x -> string_of_int (Xeneventchn.to_int x)
-
let dump d chan =
- fprintf chan "dom,%d,%nd,%d\n" d.id d.mfn d.remote_port
+ fprintf chan "dom,%d,%nd,%d\n" d.id d.mfn d.ports.remote
let rebind_evtchn d remote_port =
- begin match d.port with
- | None -> ()
- | Some p -> Event.unbind d.eventchn p
- end;
+ Event.unbind d.eventchn d.ports.local;
let local = Event.bind_interdomain d.eventchn d.id remote_port in
- debug "domain %d rebind (l %s, r %d) => (l %d, r %d)"
- d.id (string_of_port d.port) d.remote_port
- (Xeneventchn.to_int local) remote_port;
- d.remote_port <- remote_port;
- d.port <- Some (local)
+ let new_ports = { local; remote = remote_port } in
+ debug "domain %d rebind %s => %s"
+ d.id (string_of_port_pair d.ports) (string_of_port_pair new_ports);
+ d.ports <- new_ports
let notify dom =
- match dom.port with
- | None -> warn "domain %d: attempt to notify on unknown port" dom.id
- | Some port -> Event.notify dom.eventchn port
-
-let bind_interdomain dom =
- begin match dom.port with
- | None -> ()
- | Some port -> Event.unbind dom.eventchn port
- end;
- dom.port <- Some (Event.bind_interdomain dom.eventchn dom.id dom.remote_port);
- debug "bound domain %d remote port %d to local port %s" dom.id dom.remote_port (string_of_port dom.port)
-
+ Event.notify dom.eventchn dom.ports.local
let close dom =
- debug "domain %d unbound port %s" dom.id (string_of_port dom.port);
- begin match dom.port with
- | None -> ()
- | Some port -> Event.unbind dom.eventchn port
- end;
+ debug "domain %d unbind %s" dom.id (string_of_port_pair dom.ports);
+ Event.unbind dom.eventchn dom.ports.local;
+ dom.ports <- invalid_ports;
Xenmmap.unmap dom.interface
-let make id mfn remote_port interface eventchn = {
+let make id mfn remote_port interface eventchn =
+ let local = Event.bind_interdomain eventchn id remote_port in
+ let ports = { local; remote = remote_port } in
+ debug "domain %d bind %s" id (string_of_port_pair ports);
+{
id = id;
mfn = mfn;
- remote_port = remote_port;
+ ports;
interface = interface;
eventchn = eventchn;
- port = None;
bad_client = false;
io_credit = 0;
conflict_credit = !Define.conflict_burst_limit;