@@ -20,7 +20,9 @@ module Xeneventchn = Eventchn
20
20
let debug fmt = Logging. debug " connections" fmt
21
21
22
22
type t = {
23
- anonymous : (Unix .file_descr , Connection .t ) Hashtbl .t
23
+ anonymous : (Unix .file_descr , Connection .t * int ) Hashtbl .t
24
+ (* (fd -> Connection.t, index) where index maps to the poll_status array *)
25
+ ; mutable poll_status : (Unix .file_descr * Poll .event ) array
24
26
; domains : (int , Connection .t ) Hashtbl .t
25
27
; ports : (Xeneventchn .t , Connection .t ) Hashtbl .t
26
28
; mutable watches : Connection .watch list Trie .t
@@ -30,6 +32,7 @@ type t = {
30
32
let create () =
31
33
{
32
34
anonymous= Hashtbl. create 37
35
+ ; poll_status= [||]
33
36
; domains= Hashtbl. create 37
34
37
; ports= Hashtbl. create 37
35
38
; watches= Trie. create ()
@@ -43,11 +46,15 @@ let get_capacity () =
43
46
; maxwatchevents= ! Define. maxwatchevents
44
47
}
45
48
49
+ let default_poll_status () = (Unix. stdin, Poll. init_event () )
50
+
46
51
let add_anonymous cons fd =
47
52
let capacity = get_capacity () in
48
53
let xbcon = Xenbus.Xb. open_fd fd ~capacity in
49
54
let con = Connection. create xbcon None in
50
- Hashtbl. add cons.anonymous (Xenbus.Xb. get_fd xbcon) con
55
+ Hashtbl. add cons.anonymous (Xenbus.Xb. get_fd xbcon)
56
+ (con, Array. length cons.poll_status) ;
57
+ cons.poll_status < - Array. append cons.poll_status [|default_poll_status () |]
51
58
52
59
let add_domain cons dom =
53
60
let capacity = get_capacity () in
@@ -60,20 +67,26 @@ let add_domain cons dom =
60
67
Hashtbl. add cons.domains (Domain. get_id dom) con ;
61
68
Hashtbl. add cons.ports (Domain. get_local_port dom) con
62
69
63
- let select ?(only_if = fun _ -> true ) cons =
64
- Hashtbl. fold
65
- (fun _ con (ins , outs ) ->
66
- if only_if con then
67
- let fd = Connection. get_fd con in
68
- let in_fds = if Connection. can_input con then fd :: ins else ins in
69
- let out_fds = if Connection. has_output con then fd :: outs else outs in
70
- (in_fds, out_fds)
71
- else
72
- (ins, outs)
70
+ let refresh_poll_status ?(only_if = fun _ -> true ) cons =
71
+ Hashtbl. iter
72
+ (fun _ (con , index ) ->
73
+ let only = only_if con in
74
+ let fd = Connection. get_fd con in
75
+ let open Poll in
76
+ let event =
77
+ {
78
+ read= only && Connection. can_input con
79
+ ; write= only && Connection. has_output con
80
+ ; except= false
81
+ }
82
+ in
83
+ cons.poll_status.(index) < - (fd, event)
73
84
)
74
- cons.anonymous ( [] , [] )
85
+ cons.anonymous
75
86
76
- let find cons = Hashtbl. find cons.anonymous
87
+ let find cons fd =
88
+ let c, _ = Hashtbl. find cons.anonymous fd in
89
+ c
77
90
78
91
let find_domain cons = Hashtbl. find cons.domains
79
92
@@ -97,8 +110,19 @@ let del_watches cons con =
97
110
let del_anonymous cons con =
98
111
try
99
112
Hashtbl. remove cons.anonymous (Connection. get_fd con) ;
100
- del_watches cons con ;
101
- Connection. close con
113
+ (* Reallocate the poll_status array, update indices pointing to it *)
114
+ cons.poll_status < -
115
+ Array. make (Hashtbl. length cons.anonymous) (default_poll_status () ) ;
116
+ let _ =
117
+ Hashtbl. fold
118
+ (fun key (con , _ ) i ->
119
+ Hashtbl. replace cons.anonymous key (con, i) ;
120
+ i + 1
121
+ )
122
+ cons.anonymous 0
123
+ in
124
+
125
+ del_watches cons con ; Connection. close con
102
126
with exn -> debug " del anonymous %s" (Printexc. to_string exn )
103
127
104
128
let del_domain cons id =
@@ -116,7 +140,8 @@ let del_domain cons id =
116
140
117
141
let iter_domains cons fct = Hashtbl. iter (fun _ c -> fct c) cons.domains
118
142
119
- let iter_anonymous cons fct = Hashtbl. iter (fun _ c -> fct c) cons.anonymous
143
+ let iter_anonymous cons fct =
144
+ Hashtbl. iter (fun _ (c , _ ) -> fct c) cons.anonymous
120
145
121
146
let iter cons fct = iter_domains cons fct ; iter_anonymous cons fct
122
147
@@ -227,7 +252,7 @@ let stats cons =
227
252
let debug cons =
228
253
let anonymous =
229
254
Hashtbl. fold
230
- (fun _ con accu -> Connection. debug con :: accu)
255
+ (fun _ ( con , _ ) accu -> Connection. debug con :: accu)
231
256
cons.anonymous []
232
257
in
233
258
let domains =
@@ -258,6 +283,7 @@ let debug_watchevents cons con =
258
283
259
284
let filter ~f cons =
260
285
let fold _ v acc = if f v then v :: acc else acc in
261
- [] |> Hashtbl. fold fold cons.anonymous |> Hashtbl. fold fold cons.domains
286
+ let fold_a _ (v , _ ) acc = if f v then v :: acc else acc in
287
+ [] |> Hashtbl. fold fold_a cons.anonymous |> Hashtbl. fold fold cons.domains
262
288
263
289
let prevents_quit cons = filter ~f: Connection. prevents_live_update cons
0 commit comments