xref: /inferno-os/appl/collab/lib/messages.b (revision d0e1d143ef6f03c75c008c7ec648859dd260cbab)
1implement Messages;
2
3#
4# message queues and their users
5#
6
7include "messages.m";
8
9clientidgen := 1;
10
11init()
12{
13	clientidgen = 1;
14}
15
16Msglist.new(): ref Msglist
17{
18	msgs := ref Msglist;
19	msgs.tail = ref Msg;	# valid Msg when .next != nil
20	return msgs;
21}
22
23Msglist.queue(msgs: self ref Msglist): ref Msg
24{
25	return msgs.tail;
26}
27
28Msglist.wait(msgs: self ref Msglist, u: ref User, rd: ref Readreq)
29{
30	msgs.readers = (u, rd) :: msgs.readers;	# list reversed, but currently does not matter
31}
32
33Msglist.write(msgs: self ref Msglist, m: ref Msg): list of (ref User, ref Readreq)
34{
35	tail := msgs.tail;
36	tail.from = m.from;
37	tail.data = m.data;
38	tail.next = ref Msg(nil, nil, nil);
39	msgs.tail = tail.next;	# next message will be formed in tail.next
40	rl := msgs.readers;
41	msgs.readers = nil;
42	return rl;
43}
44
45Msglist.flushtag(msgs: self ref Msglist, tag: int)
46{
47	rl := msgs.readers;
48	msgs.readers = nil;
49	for(; rl != nil; rl = tl rl){
50		(nil, req) := hd rl;
51		if(req.tag != tag)
52			msgs.readers = hd rl :: msgs.readers;
53	}
54}
55
56Msglist.flushfid(msgs: self ref Msglist, fid: int)
57{
58	rl := msgs.readers;
59	msgs.readers = nil;
60	for(; rl != nil; rl = tl rl){
61		(nil, req) := hd rl;
62		if(req.fid != fid)
63			msgs.readers = hd rl :: msgs.readers;
64	}
65}
66
67User.new(fid: int, name: string): ref User
68{
69	return ref User(clientidgen++, fid, name, nil);
70}
71
72User.initqueue(u: self ref User, msgs: ref Msglist)
73{
74	u.queue = msgs.tail;
75}
76
77User.read(u: self ref User): ref Msg
78{
79	if((m := u.queue).next != nil){
80		u.queue = m.next;
81		m = ref *m;	# copy to ensure no aliasing
82		m.next = nil;
83		return m;
84	}
85	return nil;
86}
87