We must introduce an additional non_full
condition.
We also add a size
field to allow queues of different sizes.
type 'a t =
{ queue : 'a Queue.t; size : int; lock : Mutex.t;
non_empty : Condition.t; non_full : Condition.t; }
let create k =
if k > 0 then
{ queue = Queue.create (); size = k; lock = Mutex.create ();
non_empty = Condition.create (); non_full = Condition.create () }
else failwith "Tqueue.create: empty size";;
Addition is a combination of the preceding versions of the
add
and take
functions above.
let add x q =
Mutex.lock q.lock;
while Queue.length q.queue = q.size
do Condition.wait q.non_full q.lock done;
if Queue.is_empty q.queue then Condition.broadcast q.non_empty;
Queue.add q x;
Mutex.unlock q.lock;;
Removal is symmetric to addition (and must now signal non_full
when the queue is full beforehand), and is left to the reader.
We get the behavior of unbounded queues by choosing max_int
for
size
.
* * *