How do I go about using Socket.select
in Standard ML?
According to the docs, I'm supposed to pass it three lists of sockets and a timeout option
, and the function returns when any of the sockets are ready to do something (and I assume, but don't know for sure that the sockets in the out list are only the ones that need attention). However,
select
takes and returns lists of sock_desc
, and there doesn't seem to be a way of getting a socket
back from its sock_desc
. There also doesn't seem to be a way of constructing an efficient map, since it doesn't seem to be possible to order two sock_desc
s, merely compare them for equality. Once I've got the return value from select
, how do I do anything useful with the returned sockets, such as write responses out, or call accept
on them?Socket.select {
rds = readSocketDescs,
wrs = writeSocketDescs,
exs = exnSocketDescs,
timeout = SOME (Time.fromSeconds 10)
}
(**
* Produces a list of all the pairs in `listPair`, whose keys are present
* in `whiteList`. Example:
*
* ```sml
* - filterListPair op= [(1,"a"), (2,"b"), (3,"c")] [2,3];
* val it = [(2,"b"),(3,"c")] : (int * string) list
* ```
*)
fun filterListPair eq listPair whiteList =
let
fun recur listPair whiteList result =
case (listPair, whiteList) of
([], _) => result
| (_, []) => result
| ((x, y) :: xs, k :: ks) =>
if eq (x, k)
then recur xs ks ((x, y) :: result)
else recur xs whiteList result
in
List.rev (recur listPair whiteList [])
end
val sockets = [ (* what have you *) ]
val descsToSockets = List.map (fn s => (Socket.sockDesc s, s)) sockets
val { rds, wrs, exs } = Socket.select {
rds = readSocketDescs,
wrs = writeSocketDescs,
exs = exnSocketDescs,
timeout = SOME (Time.fromSeconds 10)
}
(*
* The contract of Socket.select ensures that the order in input lists
* is preserved in the output lists, so we can use `filterListPair`.
*)
val selectedReadSockets =
filterListPair Socket.sameDesc descsToSockets rds