summaryrefslogtreecommitdiff
path: root/appl/collab/lib/messages.b
blob: ab982339d7c7608dfff31506ec5d015822ac1332 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
implement Messages;

#
# message queues and their users
#

include "messages.m";

clientidgen := 1;

init()
{
	clientidgen = 1;
}

Msglist.new(): ref Msglist
{
	msgs := ref Msglist;
	msgs.tail = ref Msg;	# valid Msg when .next != nil
	return msgs;
}

Msglist.queue(msgs: self ref Msglist): ref Msg
{
	return msgs.tail;
}

Msglist.wait(msgs: self ref Msglist, u: ref User, rd: ref Readreq)
{
	msgs.readers = (u, rd) :: msgs.readers;	# list reversed, but currently does not matter
}

Msglist.write(msgs: self ref Msglist, m: ref Msg): list of (ref User, ref Readreq)
{
	tail := msgs.tail;
	tail.from = m.from;
	tail.data = m.data;
	tail.next = ref Msg(nil, nil, nil);
	msgs.tail = tail.next;	# next message will be formed in tail.next
	rl := msgs.readers;
	msgs.readers = nil;
	return rl;
}

Msglist.flushtag(msgs: self ref Msglist, tag: int)
{
	rl := msgs.readers;
	msgs.readers = nil;
	for(; rl != nil; rl = tl rl){
		(nil, req) := hd rl;
		if(req.tag != tag)
			msgs.readers = hd rl :: msgs.readers;
	}
}

Msglist.flushfid(msgs: self ref Msglist, fid: int)
{
	rl := msgs.readers;
	msgs.readers = nil;
	for(; rl != nil; rl = tl rl){
		(nil, req) := hd rl;
		if(req.fid != fid)
			msgs.readers = hd rl :: msgs.readers;
	}
}

User.new(fid: int, name: string): ref User
{
	return ref User(clientidgen++, fid, name, nil);
}

User.initqueue(u: self ref User, msgs: ref Msglist)
{
	u.queue = msgs.tail;
}

User.read(u: self ref User): ref Msg
{
	if((m := u.queue).next != nil){
		u.queue = m.next;
		m = ref *m;	# copy to ensure no aliasing
		m.next = nil;
		return m;
	}
	return nil;
}