(* multicast.sml *) structure Multicast :> MULTICAST = struct open CML structure SV = SyncVar (* streams made out of I-vars *) datatype 'a stream = Cons of 'a * 'a stream SV.ivar type 'a port = 'a chan datatype 'a request = Msg of 'a (* incoming message *) | NewPort of 'a port SV.ivar (* create a new port *) type 'a mchan = 'a request chan fun mChannel() = let val reqCh = channel() (* val mkPort : 'a stream SV.ivar -> 'a port *) fun mkPort iv = let val portCh = channel() (* val loop : 'a SV.ivar -> unit *) fun loop iv = let val Cons(v, iv') = SV.iGet iv in send(portCh, v); loop iv' end in spawn(fn () => loop iv); portCh end (* val server : 'a stream SV.ivar -> unit *) fun server iv = case recv reqCh of Msg v => let val iv' = SV.iVar() in SV.iPut(iv, Cons(v, iv')); server iv' end | NewPort replyIV => (SV.iPut(replyIV, mkPort iv); server iv) in spawn(fn () => server(SV.iVar())); reqCh end fun multicast(reqCh, v) = send(reqCh, Msg v) fun port reqCh = let val replyIV = SV.iVar() in send(reqCh, NewPort replyIV); SV.iGet replyIV end val recvEvt = CML.recvEvt end;