src/Pure/Concurrent/synchronized.scala
author wenzelm
Mon, 24 Oct 2016 12:16:12 +0200
changeset 64370 865b39487b5d
parent 56694 c4e77643aad6
child 75393 87ebf5a50283
permissions -rw-r--r--
discontinued unused / untested distinction of separate PIDE modules;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
56685
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/Concurrent/synchronized.scala
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
     3
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
     4
Synchronized variables.
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
     5
*/
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
     6
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
     7
package isabelle
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
     8
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
     9
56692
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    10
import scala.annotation.tailrec
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    11
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    12
56685
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
    13
object Synchronized
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
    14
{
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
    15
  def apply[A](init: A): Synchronized[A] = new Synchronized(init)
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
    16
}
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
    17
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
    18
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
    19
final class Synchronized[A] private(init: A)
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
    20
{
56692
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    21
  /* state variable */
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    22
56685
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
    23
  private var state: A = init
56692
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    24
56687
7fb98325722a tuned signature in accordance to ML version;
wenzelm
parents: 56685
diff changeset
    25
  def value: A = synchronized { state }
56692
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    26
  override def toString: String = value.toString
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    27
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    28
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    29
  /* synchronized access */
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    30
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    31
  def timed_access[B](time_limit: A => Option[Time], f: A => Option[(B, A)]): Option[B] =
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    32
    synchronized {
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    33
      def check(x: A): Option[B] =
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    34
        f(x) match {
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    35
          case None => None
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    36
          case Some((y, x1)) =>
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    37
            state = x1
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    38
            notifyAll()
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    39
            Some(y)
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    40
        }
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    41
      @tailrec def try_change(): Option[B] =
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    42
      {
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    43
        val x = state
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    44
        check(x) match {
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    45
          case None =>
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    46
            time_limit(x) match {
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    47
              case Some(t) =>
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    48
                val timeout = (t - Time.now()).ms
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    49
                if (timeout > 0L) {
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    50
                  wait(timeout)
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    51
                  check(state)
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    52
                }
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    53
                else None
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    54
              case None =>
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    55
                wait()
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    56
                try_change()
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    57
            }
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    58
          case some => some
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    59
        }
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    60
      }
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    61
      try_change()
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    62
    }
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    63
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    64
  def guarded_access[B](f: A => Option[(B, A)]): B =
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    65
    timed_access(_ => None, f).get
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    66
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    67
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    68
  /* unconditional change */
8219a65b24e3 synchronized access, similar to ML version;
wenzelm
parents: 56687
diff changeset
    69
56694
c4e77643aad6 proper signaling after each state update (NB: ML version does this uniformly via timed_access);
wenzelm
parents: 56692
diff changeset
    70
  def change(f: A => A): Unit = synchronized { state = f(state); notifyAll() }
c4e77643aad6 proper signaling after each state update (NB: ML version does this uniformly via timed_access);
wenzelm
parents: 56692
diff changeset
    71
56687
7fb98325722a tuned signature in accordance to ML version;
wenzelm
parents: 56685
diff changeset
    72
  def change_result[B](f: A => (B, A)): B = synchronized {
56685
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
    73
    val (result, new_state) = f(state)
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
    74
    state = new_state
56694
c4e77643aad6 proper signaling after each state update (NB: ML version does this uniformly via timed_access);
wenzelm
parents: 56692
diff changeset
    75
    notifyAll()
56685
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
    76
    result
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
    77
  }
535d59d4ed12 more uniform synchronized variables;
wenzelm
parents:
diff changeset
    78
}