blob: 5940628124101712bb45740a00633edb77ac01d7 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2005-2009, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
// $Id$
package scala.actors
import java.lang.{InterruptedException, Runnable}
/** <p>
* This exception is thrown whenever an actor exits.
* Its purpose is to let <code>exit</code> have
* return type <code>Nothing</code>.
* </p>
*
* @version 0.9.10
* @author Philipp Haller
*/
private[actors] class ExitActorException extends Throwable {
/*
* For efficiency reasons we do not fill in
* the execution stack trace.
*/
override def fillInStackTrace(): Throwable = this
}
private[actors] class KillActorException extends Throwable {
/*
* For efficiency reasons we do not fill in
* the execution stack trace.
*/
override def fillInStackTrace(): Throwable = this
}
/** <p>
* The abstract class <code>Reaction</code> associates
* an instance of an <code>Actor</code> with a
* <a class="java/lang/Runnable" href="" target="contentFrame">
* <code>java.lang.Runnable</code></a>.
* </p>
*
* @version 0.9.10
* @author Philipp Haller
*/
class Reaction extends Runnable {
private[actors] var a: Actor = _
private var f: PartialFunction[Any, Unit] = _
private var msg: Any = _
def this(a: Actor, f: PartialFunction[Any, Unit], msg: Any) = {
this()
this.a = a
this.f = f
this.msg = msg
}
def this(a: Actor) = this(a, null, null)
def run() {
val saved = Actor.tl.get.asInstanceOf[Actor]
Actor.tl.set(a)
a.isDetached = false
try {
if (a.shouldExit) // links
a.exit()
else {
try {
if (f == null)
a.act()
else
f(msg)
} catch {
case _: KillActorException =>
}
a.kill(); a.exit()
}
}
catch {
case eae: ExitActorException => {
//Debug.info(a+": exiting...")
ActorGC.terminated(a)
}
case _: SuspendActorException => {
// do nothing (continuation is already saved)
}
case t: Throwable => {
Debug.info(a+": caught "+t)
ActorGC.terminated(a)
// links
a.synchronized {
if (!a.links.isEmpty)
a.exitLinked(t)
else
t.printStackTrace()
}
}
} finally {
Actor.tl.set(saved)
}
}
}
|