aboutsummaryrefslogtreecommitdiffhomepage
path: root/stm/tQueue.ml
diff options
context:
space:
mode:
authorGravatar Enrico Tassi <Enrico.Tassi@inria.fr>2014-12-11 14:29:47 +0100
committerGravatar Enrico Tassi <Enrico.Tassi@inria.fr>2014-12-17 15:05:05 +0100
commitf9a6efbb2647e7856c34966fd7bcc00a1d8fbc4d (patch)
tree2a19dda07a4ea19b4084f43476f62b1bb734d1f6 /stm/tQueue.ml
parentf5a0e2136dacf635c2790099972961b086665a38 (diff)
TQueue: a way to unblock threads begin destroyed waiting on pop
Diffstat (limited to 'stm/tQueue.ml')
-rw-r--r--stm/tQueue.ml14
1 files changed, 10 insertions, 4 deletions
diff --git a/stm/tQueue.ml b/stm/tQueue.ml
index 00213b8a2..834f93681 100644
--- a/stm/tQueue.ml
+++ b/stm/tQueue.ml
@@ -60,24 +60,30 @@ let create () = {
release = false;
}
-let pop ?(picky=(fun _ -> true))
+let pop ?(picky=(fun _ -> true)) ?(destroy=ref false)
({ queue = q; lock = m; cond = c; cond_waiting = cn } as tq)
=
- if tq.release then raise BeingDestroyed;
Mutex.lock m;
- while not (PriorityQueue.exists picky q) do
+ if tq.release then (Mutex.unlock m; raise BeingDestroyed);
+ while not (PriorityQueue.exists picky q || !destroy) do
tq.nwaiting <- tq.nwaiting + 1;
Condition.broadcast cn;
Condition.wait c m;
tq.nwaiting <- tq.nwaiting - 1;
- if tq.release then (Mutex.unlock m; raise BeingDestroyed)
+ if tq.release || !destroy then (Mutex.unlock m; raise BeingDestroyed)
done;
+ if !destroy then (Mutex.unlock m; raise BeingDestroyed);
let x = PriorityQueue.pop ~picky q in
Condition.signal c;
Condition.signal cn;
Mutex.unlock m;
x
+let signal_destruction { lock = m; cond = c } =
+ Mutex.lock m;
+ Condition.broadcast c;
+ Mutex.unlock m
+
let push { queue = q; lock = m; cond = c; release } x =
if release then Errors.anomaly(Pp.str
"TQueue.push while being destroyed! Only 1 producer/destroyer allowed");