Limbo channels are unbuffered; a sender blocks until there is a receiver. This example shows a way to make a buffered channel of strings from an unbuffered channel. It is written as a module whose bufchan function takes a chan of string and a size as argument, and returns a new channel; it creates an asynchronous task that accepts input from the argument channel and saves up to size strings, meanwhile trying to send them to its user.
implement Bufchan;
Bufchan: module {
bufchan: fn(c: chan of string, size: int): chan of string;
};
xfer(oldchan, newchan: chan of string, size: int)
{
temp := array[size] of string;
fp := 0; # first string in buffer
n := 0; # number of strings in buffer
dummy := chan of string;
sendch, recvch: chan of string;
s: string;
for (;;) {
sendch = recvch = dummy;
if (n > 0)
sendch = newchan;
if (n < size)
recvch = oldchan;
alt {
s = <-recvch =>
temp[(fp+n)%size] = s;
n++;
sendch <- = temp[fp] =>
temp[fp++] = nil;
n--;
if (fp>=size)
fp -= size;
}
}
}
bufchan(oldchan: chan of string, size: int): chan of string
{
newchan := chan of string;
spawn xfer(oldchan, newchan, size);
return newchan;
}
The module could be used in the following way:
Bufchan: module {
PATH: con "/appl/lib/bufchan.dis";
bufchan: fn(c: chan of string, size: int): chan of string;
};
. . .
bufc := load Bufchan Bufchan->PATH;
sourcech := chan of string;
# ... (here, hand off sourcech to a process that
# reads strings from it and copies them to ch)
ch: chan of string = bufc->bufchan(sourcech, 10);
. . .
s := <- ch;
. . .