summaryrefslogtreecommitdiff
path: root/src/actors/scala/actors/scheduler/DelegatingScheduler.scala
blob: b8a81d11a96b8e6cdd212912cea62d6900be233b (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
/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2005-2013, LAMP/EPFL             **
**  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
\*                                                                      */

package scala.actors
package scheduler

import scala.concurrent.ManagedBlocker

/**
 * @author Erik Engbrecht
 */
private[actors] trait DelegatingScheduler extends IScheduler {
  protected def makeNewScheduler(): IScheduler

  protected var sched: IScheduler = null

  final def impl = synchronized {
    if ((sched eq null) || (!sched.isActive))
      sched = makeNewScheduler()
    sched
  }

  final def impl_= (scheduler: IScheduler): Unit = synchronized {
    //TODO: if there is already a scheduler, should it be shutdown?
    sched = scheduler
  }

  /**
   * Always active because it will just make a new scheduler if required
   */
  def isActive: Boolean = true

  def execute(fun: => Unit) = impl.execute(fun)

  def execute(task: Runnable) = impl.execute(task)

  override def executeFromActor(task: Runnable) = impl.executeFromActor(task)

  def shutdown(): Unit = synchronized {
    if (sched ne null) {
      sched.shutdown()
      sched = null
    }
  }

  def newActor(actor: TrackedReactor) = synchronized {
    val createNew = if (sched eq null)
      true
    else sched.synchronized {
      if (!sched.isActive)
        true
      else {
        sched.newActor(actor)
        false
      }
    }
    if (createNew) {
      sched = makeNewScheduler()
      sched.newActor(actor)
    }
  }

  def terminated(actor: TrackedReactor) = impl.terminated(actor)

  def onTerminate(actor: TrackedReactor)(f: => Unit) = impl.onTerminate(actor)(f)

  override def managedBlock(blocker: ManagedBlocker): Unit =
    impl.managedBlock(blocker)
}