src/Pure/Concurrent/delay.scala
author wenzelm
Sun, 28 Mar 2021 11:45:00 +0200
changeset 73503 eda1d95ef538
parent 73367 77ef8bef0593
child 75380 2cb2606ce075
permissions -rw-r--r--
misc tuning and clarification;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
71704
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/Concurrent/delay.scala
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
     3
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
     4
Delayed events.
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
     5
*/
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
     6
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
     7
package isabelle
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
     8
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
     9
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    10
object Delay
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    11
{
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    12
  // delayed event after first invocation
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    13
  def first(delay: => Time, log: Logger = No_Logger, gui: Boolean = false)(event: => Unit): Delay =
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    14
    new Delay(true, delay, log, if (gui) GUI_Thread.later { event } else event )
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    15
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    16
  // delayed event after last invocation
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    17
  def last(delay: => Time, log: Logger = No_Logger, gui: Boolean = false)(event: => Unit): Delay =
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    18
    new Delay(false, delay, log, if (gui) GUI_Thread.later { event } else event )
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    19
}
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    20
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    21
final class Delay private(first: Boolean, delay: => Time, log: Logger, event: => Unit)
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    22
{
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    23
  private var running: Option[Event_Timer.Request] = None
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    24
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    25
  private def run: Unit =
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    26
  {
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    27
    val do_run = synchronized {
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    28
      if (running.isDefined) { running = None; true } else false
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    29
    }
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    30
    if (do_run) {
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    31
      try { event }
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    32
      catch { case exn: Throwable if !Exn.is_interrupt(exn) => log(Exn.message(exn)); throw exn }
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    33
    }
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    34
  }
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    35
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    36
  def invoke(): Unit = synchronized
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    37
  {
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    38
    val new_run =
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    39
      running match {
73367
77ef8bef0593 clarified signature --- fewer warnings;
wenzelm
parents: 71704
diff changeset
    40
        case Some(request) => if (first) false else { request.cancel(); true }
71704
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    41
        case None => true
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    42
      }
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    43
    if (new_run)
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    44
      running = Some(Event_Timer.request(Time.now() + delay)(run))
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    45
  }
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    46
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    47
  def revoke(): Unit = synchronized
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    48
  {
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    49
    running match {
73367
77ef8bef0593 clarified signature --- fewer warnings;
wenzelm
parents: 71704
diff changeset
    50
      case Some(request) => request.cancel(); running = None
71704
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    51
      case None =>
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    52
    }
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    53
  }
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    54
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    55
  def postpone(alt_delay: Time): Unit = synchronized
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    56
  {
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    57
    running match {
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    58
      case Some(request) =>
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    59
        val alt_time = Time.now() + alt_delay
73367
77ef8bef0593 clarified signature --- fewer warnings;
wenzelm
parents: 71704
diff changeset
    60
        if (request.time < alt_time && request.cancel()) {
71704
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    61
          running = Some(Event_Timer.request(alt_time)(run))
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    62
        }
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    63
      case None =>
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    64
    }
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    65
  }
b9a5eb0f3b43 clarified modules;
wenzelm
parents:
diff changeset
    66
}