From 8322730ecf690e9b93d49286667e06245086c367 Mon Sep 17 00:00:00 2001 From: michelou Date: Tue, 10 Oct 2006 21:35:36 +0000 Subject: cleaned up comments in scala/actors/*.scala --- src/actors/scala/actors/Actor.scala | 180 ++++++++++++++++++++------------ src/actors/scala/actors/Scheduler.scala | 110 ++++++++++--------- 2 files changed, 171 insertions(+), 119 deletions(-) (limited to 'src/actors') diff --git a/src/actors/scala/actors/Actor.scala b/src/actors/scala/actors/Actor.scala index 47793a88f3..c3f2f2d409 100644 --- a/src/actors/scala/actors/Actor.scala +++ b/src/actors/scala/actors/Actor.scala @@ -10,11 +10,11 @@ package scala.actors -import scala.collection.mutable.HashSet +import scala.collection.mutable.{HashSet, Stack} /** - * This object provides functions for the definition of actors, - * as well as all actor operations, such as + * The Actor object provides functions for the definition of + * actors, as well as all actor operations, such as * receive, react, reply, * etc. * @@ -29,6 +29,8 @@ object Actor { * Returns the currently executing actor. Should be used instead * of this in all blocks of code executed by * actors. + * + * @return returns the currently executing actor. */ def self: Actor = synchronized { val t = Thread.currentThread() @@ -68,39 +70,52 @@ object Actor { * Receives a message from the mailbox of * self. Blocks if no message matching any of the * cases of f can be received. + * + * @param f ... + * @return ... */ def receive[a](f: PartialFunction[Any, a]): a = self.in.receive(f) /** - Receives a message from the mailbox of - self. Blocks at most msec - milliseconds if no message matching any of the cases of - f can be received. If no message could be - received the TIMEOUT action is executed if - specified. + * Receives a message from the mailbox of + * self. Blocks at most msec + * milliseconds if no message matching any of the cases of + * f can be received. If no message could be + * received the TIMEOUT action is executed if + * specified. + * + * @param msec ... + * @param f ... + * @return ... */ def receiveWithin[R](msec: long)(f: PartialFunction[Any, R]): R = self.in.receiveWithin(msec)(f) /** - receive for event-based reactors. - - Actions in f have to contain the rest of the - computation of self, as this method will never - return. + * receive for event-based reactors. + * + * Actions in f have to contain the rest of the + * computation of self, as this method will never + * return. + * + * @param f ... + * @return ... */ def react(f: PartialFunction[Any, Unit]): Nothing = self.in.react(f) /** - receiveWithin for event-based reactors. - - Actions in f have to contain the rest of the - computation of self, as this method will never - return. + * receiveWithin for event-based reactors. + * + * Actions in f have to contain the rest of the + * computation of self, as this method will never + * return. + * + * @param msec ... + * @param f ... + * @return ... */ - def reactWithin(msec: long)(f: PartialFunction[Any, Unit]): Nothing = self.in.reactWithin(msec)(f) @@ -120,8 +135,11 @@ object Actor { */ /** - Used for receiving a message from a specific actor. - Example: from (a) receive { //... } + *

Used for receiving a message from a specific actor.

+ *

Example:

from (a) receive { //... } + * + * @param r ... + * @return ... */ def from(r: Actor): FromReceive = new FromReceive(r) @@ -132,19 +150,19 @@ object Actor { } /** - Returns the actor which sent the last received message. + * Returns the actor which sent the last received message. */ def sender: Actor = self.sender /** - Send msg to the actor waiting in a call to - !?. + * Send msg to the actor waiting in a call to + * !?. */ def reply(msg: Any): Unit = sender.reply ! msg /** - Send () to the actor waiting in a call to - !?. + * Send () to the actor waiting in a call to + * !?. */ def reply(): Unit = reply(()) @@ -170,18 +188,20 @@ object Actor { s.suspendActor = () => { throw new SuspendActorException } s.detachActor = f => { throw new SuspendActorException } - try { alt1 } catch { - case d: SuspendActorException => { + try { alt1 } + catch { + case d: SuspendActorException => s.suspendActor = suspendNext s.detachActor = detachNext alt2 - } } } /** - Causes self to repeatedly execute - body. + * Causes self to repeatedly execute + * body. + * + * @param body ... */ def loop(body: => Unit): Unit = { val s = self @@ -190,8 +210,11 @@ object Actor { } /** - Causes self to execute first - followed by next. + * Causes self to execute first + * followed by next. + * + * @param first ... + * @param next ... */ def seq(first: => Unit, next: => Unit): Unit = { val s = self @@ -200,42 +223,58 @@ object Actor { } /** - Links self to actor to. + * Links self to actor to. + * + * @param to ... + * @return ... */ def link(to: Actor): Actor = self.link(to) /** - Links self to actor defined by body. + * Links self to actor defined by body. + * + * @param body ... + * @return ... */ def link(body: => Unit): Actor = self.link(body) /** - Unlinks self from actor from. + * Unlinks self from actor from. + * + * @param from ... */ def unlink(from: Actor): Unit = self.unlink(from) /** - Terminates execution of self with the following - effect on linked actors: - - For each linked actor a with - trapExit set to true, send message - Exit(self, reason) to a. - - For each linked actor a with - trapExit set to false (default), - call a.exit(reason) if - !reason.equals("normal"). + *

+ * Terminates execution of self with the following + * effect on linked actors: + *

+ *

+ * For each linked actor a with + * trapExit set to true, send message + * Exit(self, reason) to a. + *

+ *

+ * For each linked actor a with + * trapExit set to false (default), + * call a.exit(reason) if + * !reason.equals("normal"). + *

*/ def exit(reason: String): Unit = self.exit(reason) } /** - * This class provides (together with Channel) an - * implementation of event-based actors. - * - * The main ideas of our approach are explained in the paper
- * Event-Based Programming without Inversion of Control, Philipp Haller, Martin Odersky Proc. JMLC 2006 + *

+ * This class provides (together with Channel) an + * implementation of event-based actors. + *

+ *

+ * The main ideas of our approach are explained in the paper
+ * Event-Based Programming without Inversion of Control, + * Philipp Haller, Martin Odersky Proc. JMLC 2006 + *

* * @version Beta2 * @author Philipp Haller @@ -280,7 +319,7 @@ trait Actor extends OutputChannel[Any] { */ def !?(msg: Any): Any = in !? msg - private val lastSenders = new scala.collection.mutable.Stack[Actor] + private val lastSenders = new Stack[Actor] private[actors] def sender: Actor = { if (lastSenders.isEmpty) null @@ -338,7 +377,10 @@ trait Actor extends OutputChannel[Any] { private val links = new HashSet[Actor] /** - Links self to actor to. + * Links self to actor to. + * + * @param to ... + * @return ... */ def link(to: Actor): Actor = { links += to @@ -347,7 +389,7 @@ trait Actor extends OutputChannel[Any] { } /** - Links self to actor defined by body. + * Links self to actor defined by body. */ def link(body: => Unit): Actor = { val actor = new Actor { @@ -377,17 +419,21 @@ trait Actor extends OutputChannel[Any] { private[actors] var exitReason: String = "" /** - Terminates execution of self with the following - effect on linked actors: - - For each linked actor a with - trapExit set to true, send message - Exit(self, reason) to a. - - For each linked actor a with - trapExit set to false (default), - call a.exit(reason) if - !reason.equals("normal"). + *

+ * Terminates execution of self with the following + * effect on linked actors: + *

+ *

+ * For each linked actor a with + * trapExit set to true, send message + * Exit(self, reason) to a. + *

+ *

+ * For each linked actor a with + * trapExit set to false (default), + * call a.exit(reason) if + * !reason.equals("normal"). + *

*/ def exit(reason: String): Unit = { exitReason = reason diff --git a/src/actors/scala/actors/Scheduler.scala b/src/actors/scala/actors/Scheduler.scala index 8f27ce22a2..870eb0618e 100644 --- a/src/actors/scala/actors/Scheduler.scala +++ b/src/actors/scala/actors/Scheduler.scala @@ -73,7 +73,7 @@ class SingleThreadedScheduler extends IScheduler { task.run() } - def getTask(worker: WorkerThread): Runnable = { null } + def getTask(worker: WorkerThread): Runnable = null def tick(a: Actor): Unit = {} @@ -195,12 +195,12 @@ class TickedScheduler extends IScheduler { while (iter.hasNext && !foundBusy) { val wt = iter.next ticks.get(wt) match { - case None => foundBusy = true // assume not blocked - case Some(ts) => { + case None => + foundBusy = true // assume not blocked + case Some(ts) => val currTime = System.currentTimeMillis if (currTime - ts < TICKFREQ) foundBusy = true - } } } @@ -238,7 +238,9 @@ class TickedScheduler extends IScheduler { def tick(a: Actor): unit = synchronized { ticksCnt = ticksCnt + 1 executing.get(a) match { - case None => // thread outside of scheduler; error("No worker thread associated with actor " + a) + case None => + // thread outside of scheduler; + // error("No worker thread associated with actor " + a) case Some(wt) => ticks.update(wt, System.currentTimeMillis) } @@ -271,47 +273,53 @@ class QuitException extends Throwable { /** - * The class WorkerThread is used by schedulers to execute - * actor tasks on multiple threads. - * - * !!ACHTUNG: If you change this, make sure you understand the following - * proof of deadlock-freedom!! - * - * We proof that there is no deadlock between the scheduler and - * any worker thread possible. For this, note that the scheduler - * only acquires the lock of a worker thread by calling - * `execute'. This method is only called when the worker thread - * is in the idle queue of the scheduler. On the other hand, a - * worker thread only acquires the lock of the scheduler when it - * calls `getTask'. At the only callsite of `getTask', the - * worker thread holds its own lock. - * - * Thus, deadlock can only occur when a worker thread calls - * `getTask' while it is in the idle queue of the scheduler, - * because then the scheduler might call (at any time!) `execute' - * which tries to acquire the lock of the worker thread. In such - * a situation the worker thread would be waiting to acquire the - * lock of the scheduler and vice versa. - * - * Therefore, to prove deadlock-freedom, it suffices to ensure - * that a worker thread will never call `getTask' when it is in - * the idle queue of the scheduler. - * - * A worker thread enters the idle queue of the scheduler when - * `getTask' returns null. Then it will also stay - * in the while-loop W (while (task == null)) until - * `task' becomes non-null. The only way this can happen is - * through a call of `execute' by the scheduler. Before every - * call of `execute' the worker thread is removed from the idle - * queue of the scheduler. Only then--after executing its task-- - * the worker thread may call `getTask'. However, the scheduler - * is unable to call `execute' as the worker thread is not in - * the idle queue any more. In fact, the scheduler made sure - * that this is the case even _before_ calling `execute' and - * thus releasing the worker thread from the while-loop W. Thus, - * the property holds for every possible interleaving of thread - * execution. QED - * + *

+ * The class WorkerThread is used by schedulers to execute + * actor tasks on multiple threads. + *

+ *

+ * !!ACHTUNG: If you change this, make sure you understand the following + * proof of deadlock-freedom!! + *

+ *

+ * We proof that there is no deadlock between the scheduler and + * any worker thread possible. For this, note that the scheduler + * only acquires the lock of a worker thread by calling + * execute. This method is only called when the worker thread + * is in the idle queue of the scheduler. On the other hand, a + * worker thread only acquires the lock of the scheduler when it + * calls getTask. At the only callsite of getTask, + * the worker thread holds its own lock. + *

+ *

+ * Thus, deadlock can only occur when a worker thread calls + * getTask while it is in the idle queue of the scheduler, + * because then the scheduler might call (at any time!) execute + * which tries to acquire the lock of the worker thread. In such + * a situation the worker thread would be waiting to acquire the + * lock of the scheduler and vice versa. + *

+ *

+ * Therefore, to prove deadlock-freedom, it suffices to ensure + * that a worker thread will never call getTask when + * it is in the idle queue of the scheduler. + *

+ *

+ * A worker thread enters the idle queue of the scheduler when + * getTask returns null. Then it will also stay + * in the while-loop W (while (task == null)) until + * task becomes non-null. The only way this can happen is + * through a call of execute by the scheduler. Before every + * call of execute the worker thread is removed from the idle + * queue of the scheduler. Only then--after executing its task-- + * the worker thread may call getTask. However, the scheduler + * is unable to call execute as the worker thread is not in + * the idle queue any more. In fact, the scheduler made sure + * that this is the case even _before_ calling execute and + * thus releasing the worker thread from the while-loop W. Thus, + * the property holds for every possible interleaving of thread + * execution. QED + *

* * @version Beta2 * @author Philipp Haller @@ -325,16 +333,15 @@ class WorkerThread(sched: IScheduler) extends Thread { notify() } - override def run(): Unit = { + override def run(): Unit = try { while (running) { if (task != null) { try { task.run() } catch { - case consumed: InterruptedException => { + case consumed: InterruptedException => if (!running) throw new QuitException - } } } this.synchronized { @@ -344,9 +351,8 @@ class WorkerThread(sched: IScheduler) extends Thread { try { wait() } catch { - case consumed: InterruptedException => { + case consumed: InterruptedException => if (!running) throw new QuitException - } } } @@ -359,5 +365,5 @@ class WorkerThread(sched: IScheduler) extends Thread { case consumed: QuitException => // allow thread to quit } - } + } -- cgit v1.2.3