2
** ________ ___ / / ___ Scala API **
3
** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
4
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5
** /____/\___/_/ |_/____/_/ | | **
11
package scala.concurrent
15
* @author Martin Odersky
16
* @version 1.0, 12/03/2003
18
//class MailBox with Monitor with LinkedListQueueCreator {
19
@deprecated("use actors instead", "2.8.0")
20
class MailBox extends AnyRef with ListQueueCreator {
24
private abstract class PreReceiver {
25
var msg: Message = null
26
def isDefinedAt(msg: Message): Boolean
29
private class Receiver[A](receiver: PartialFunction[Message, A]) extends PreReceiver {
31
def isDefinedAt(msg: Message) = receiver.isDefinedAt(msg)
33
def receive(): A = synchronized {
34
while (msg eq null) wait()
38
def receiveWithin(msec: Long): A = synchronized {
39
if (msg eq null) wait(msec)
40
receiver(if (msg ne null) msg else TIMEOUT)
44
private val messageQueue = queueCreate[Message]
45
private val receiverQueue = queueCreate[PreReceiver]
47
/** Unconsumed messages. */
48
private var sent = messageQueue.make
50
/** Pending receivers. */
51
private var receivers = receiverQueue.make
54
* Check whether the receiver can be applied to an unconsumed message.
55
* If yes, the message is extracted and associated with the receiver.
56
* Otherwise the receiver is appended to the list of pending receivers.
58
private def scanSentMsgs[A](receiver: Receiver[A]): Unit = synchronized {
59
messageQueue.extractFirst(sent, msg => receiver.isDefinedAt(msg)) match {
61
receivers = receiverQueue.append(receivers, receiver)
62
case Some((msg, withoutMsg)) =>
69
* First check whether a pending receiver is applicable to the sent
70
* message. If yes, the receiver is notified. Otherwise the message
71
* is appended to the linked list of sent messages.
73
def send(msg: Message): Unit = synchronized {
74
receiverQueue.extractFirst(receivers, r => r.isDefinedAt(msg)) match {
76
sent = messageQueue.append(sent, msg)
77
case Some((receiver, withoutReceiver)) =>
78
receivers = withoutReceiver
80
receiver synchronized { receiver.notify() }
85
* Block until there is a message in the mailbox for which the processor
86
* <code>f</code> is defined.
88
def receive[A](f: PartialFunction[Message, A]): A = {
89
val r = new Receiver(f)
95
* Block until there is a message in the mailbox for which the processor
96
* <code>f</code> is defined or the timeout is over.
98
def receiveWithin[A](msec: Long)(f: PartialFunction[Message, A]): A = {
99
val r = new Receiver(f)
101
r.receiveWithin(msec)
109
* Module for dealing with queues.
111
@deprecated("use actors instead", "2.8.0")
112
trait QueueModule[A] {
113
/** Type of queues. */
115
/** Create an empty queue. */
117
/** Append an element to a queue. */
118
def append(l: T, x: A): T
119
/** Extract an element satisfying a predicate from a queue. */
120
def extractFirst(l: T, p: A => Boolean): Option[(A, T)]
123
/** Inefficient but simple queue module creator. */
124
@deprecated("use actors instead", "2.8.0")
125
trait ListQueueCreator {
126
def queueCreate[A]: QueueModule[A] = new QueueModule[A] {
129
def append(l: T, x: A): T = l ::: x :: Nil
130
def extractFirst(l: T, p: A => Boolean): Option[(A, T)] =
137
extractFirst(tail, p) match {
139
case Some((x, without_x)) => Some((x, head :: without_x))
145
/** Efficient queue module creator based on linked lists. */
146
@deprecated("use actors instead", "2.8.0")
147
trait LinkedListQueueCreator {
148
import scala.collection.mutable.LinkedList
149
def queueCreate[A >: Null <: AnyRef]: QueueModule[A] = new QueueModule[A] {
150
type T = (LinkedList[A], LinkedList[A]) // fst = the list, snd = last elem
152
val l = new LinkedList[A](null, null)
155
def append(l: T, x: A): T = {
156
val atTail = new LinkedList(x, null)
160
def extractFirst(l: T, p: A => Boolean): Option[(A, T)] = {
163
while ((xs1 ne null) && !p(xs1.elem)) {
170
Some((xs1.elem, (l._1, xs)))