@@ -22,7 +22,7 @@ let debug fmt = Logging.debug "connections" fmt
22
22
type t = {
23
23
anonymous : (Unix .file_descr , Connection .t * int ) Hashtbl .t
24
24
(* (fd -> Connection.t, index) where index maps to the poll_status array *)
25
- ; mutable poll_status : ( Unix .file_descr * Poll .event ) array
25
+ ; mutable poll_status : Poll .poll_status_t array
26
26
; domains : (int , Connection .t ) Hashtbl .t
27
27
; ports : (Xeneventchn .t , Connection .t ) Hashtbl .t
28
28
; mutable watches : Connection .watch list Trie .t
@@ -46,7 +46,15 @@ let get_capacity () =
46
46
; maxwatchevents= ! Define. maxwatchevents
47
47
}
48
48
49
- let default_poll_status () = (Unix. stdin, Poll. init_event () )
49
+ let default_poll_status () = Poll. {fd= Unix. stdin; event= init_event () }
50
+
51
+ let spec_poll_status_new () = Poll. {read= true ; write= false ; except= false }
52
+
53
+ let spec_poll_status event =
54
+ let open Poll in
55
+ event.read < - true ;
56
+ event.write < - false ;
57
+ event.except < - false
50
58
51
59
let add_anonymous cons fd =
52
60
let capacity = get_capacity () in
@@ -67,20 +75,23 @@ let add_domain cons dom =
67
75
Hashtbl. replace cons.domains (Domain. get_id dom) con ;
68
76
Hashtbl. replace cons.ports (Domain. get_local_port dom) con
69
77
70
- let refresh_poll_status ?(only_if = fun _ -> true ) cons =
78
+ let refresh_poll_status ?(only_if = fun _ -> true ) cons spec_fds =
79
+ (* special fds are always read=true, but get overwritten by select_stubs, so we
80
+ need to reset the event we are polling for *)
81
+ List. iteri
82
+ (fun index fd ->
83
+ cons.poll_status.(index).fd < - fd ;
84
+ spec_poll_status cons.poll_status.(index).event
85
+ )
86
+ spec_fds ;
71
87
Hashtbl. iter
72
88
(fun _ (con , index ) ->
73
89
let only = only_if con in
74
- let fd = Connection. get_fd con in
90
+ cons.poll_status.(index). fd < - Connection. get_fd con ;
75
91
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)
92
+ cons.poll_status.(index).event.read < - only && Connection. can_input con ;
93
+ cons.poll_status.(index).event.write < - only && Connection. has_output con ;
94
+ cons.poll_status.(index).event.except < - false
84
95
)
85
96
cons.anonymous
86
97
@@ -107,19 +118,33 @@ let del_watches cons con =
107
118
|> Connection.Watch.Set. filter @@ fun w -> Connection. get_con w != con
108
119
)
109
120
110
- let del_anonymous cons con =
121
+ let del_anonymous cons con spec_fds =
111
122
try
112
123
Hashtbl. remove cons.anonymous (Connection. get_fd con) ;
113
124
(* Reallocate the poll_status array, update indices pointing to it *)
114
125
cons.poll_status < -
115
- Array. make (Hashtbl. length cons.anonymous) (default_poll_status () ) ;
126
+ Array. make
127
+ (Hashtbl. length cons.anonymous + List. length spec_fds)
128
+ (default_poll_status () ) ;
129
+
130
+ (* Keep the special fds at the beginning *)
131
+ let i =
132
+ List. fold_left
133
+ (fun index fd ->
134
+ cons.poll_status.(index).fd < - fd ;
135
+ spec_poll_status cons.poll_status.(index).event ;
136
+ index + 1
137
+ )
138
+ 0 spec_fds
139
+ in
140
+
116
141
let _ =
117
142
Hashtbl. fold
118
143
(fun key (con , _ ) i ->
119
144
Hashtbl. replace cons.anonymous key (con, i) ;
120
145
i + 1
121
146
)
122
- cons.anonymous 0
147
+ cons.anonymous i
123
148
in
124
149
125
150
del_watches cons con ; Connection. close con
0 commit comments