| author | paulson <lp15@cam.ac.uk> | 
| Thu, 10 Apr 2025 17:07:18 +0100 | |
| changeset 82470 | 785615e37846 | 
| parent 78865 | a0199212046a | 
| permissions | -rw-r--r-- | 
| 56693 | 1  | 
/* Title: Pure/Concurrent/mailbox.scala  | 
2  | 
Author: Makarius  | 
|
3  | 
||
| 
57417
 
29fe9bac501b
more tight Mailbox: single list is sufficient for single receiver, reverse outside critical section;
 
wenzelm 
parents: 
56693 
diff
changeset
 | 
4  | 
Message exchange via mailbox, with multiple senders (non-blocking,  | 
| 
 
29fe9bac501b
more tight Mailbox: single list is sufficient for single receiver, reverse outside critical section;
 
wenzelm 
parents: 
56693 
diff
changeset
 | 
5  | 
unbounded buffering) and single receiver (bulk messages).  | 
| 56693 | 6  | 
*/  | 
7  | 
||
8  | 
package isabelle  | 
|
9  | 
||
10  | 
||
| 75393 | 11  | 
object Mailbox {
 | 
| 78865 | 12  | 
def apply[A](limit: Int = 0): Mailbox[A] = new Mailbox[A](limit)  | 
| 56693 | 13  | 
}  | 
14  | 
||
15  | 
||
| 78865 | 16  | 
class Mailbox[A] private(limit: Int) {
 | 
| 61590 | 17  | 
private val mailbox = Synchronized[List[A]](Nil)  | 
| 
57417
 
29fe9bac501b
more tight Mailbox: single list is sufficient for single receiver, reverse outside critical section;
 
wenzelm 
parents: 
56693 
diff
changeset
 | 
18  | 
  override def toString: String = mailbox.value.reverse.mkString("Mailbox(", ",", ")")
 | 
| 56693 | 19  | 
|
| 78865 | 20  | 
def send(msg: A): Unit =  | 
21  | 
if (limit <= 0) mailbox.change(msg :: _)  | 
|
22  | 
else mailbox.guarded_access(msgs => if (msgs.length < limit) Some(((), msg :: msgs)) else None)  | 
|
| 56693 | 23  | 
|
| 71144 | 24  | 
def receive(timeout: Option[Time] = None): List[A] =  | 
| 
57417
 
29fe9bac501b
more tight Mailbox: single list is sufficient for single receiver, reverse outside critical section;
 
wenzelm 
parents: 
56693 
diff
changeset
 | 
25  | 
(mailbox.timed_access(_ => timeout.map(t => Time.now() + t),  | 
| 
 
29fe9bac501b
more tight Mailbox: single list is sufficient for single receiver, reverse outside critical section;
 
wenzelm 
parents: 
56693 
diff
changeset
 | 
26  | 
      { case Nil => None case msgs => Some((msgs, Nil)) }) getOrElse Nil).reverse
 | 
| 56693 | 27  | 
|
| 78864 | 28  | 
def await_empty(): Unit =  | 
| 
57417
 
29fe9bac501b
more tight Mailbox: single list is sufficient for single receiver, reverse outside critical section;
 
wenzelm 
parents: 
56693 
diff
changeset
 | 
29  | 
    mailbox.guarded_access({ case Nil => Some(((), Nil)) case _ => None })
 | 
| 56693 | 30  | 
}  |