src/Pure/PIDE/session.scala
changeset 68381 2fd3a6d6ba2e
parent 68336 09ac56914b29
child 68382 b10ae73f0bab
equal deleted inserted replaced
68380:f249e1f5623b 68381:2fd3a6d6ba2e
    48   sealed case class Change(
    48   sealed case class Change(
    49     previous: Document.Version,
    49     previous: Document.Version,
    50     syntax_changed: List[Document.Node.Name],
    50     syntax_changed: List[Document.Node.Name],
    51     deps_changed: Boolean,
    51     deps_changed: Boolean,
    52     doc_edits: List[Document.Edit_Command],
    52     doc_edits: List[Document.Edit_Command],
    53     consolidate: Boolean,
    53     consolidate: List[Document.Node.Name],
    54     version: Document.Version)
    54     version: Document.Version)
    55 
    55 
    56   case object Change_Flush
    56   case object Change_Flush
    57 
    57 
    58 
    58 
   229 
   229 
   230   private case class Text_Edits(
   230   private case class Text_Edits(
   231     previous: Future[Document.Version],
   231     previous: Future[Document.Version],
   232     doc_blobs: Document.Blobs,
   232     doc_blobs: Document.Blobs,
   233     text_edits: List[Document.Edit_Text],
   233     text_edits: List[Document.Edit_Text],
   234     consolidate: Boolean,
   234     consolidate: List[Document.Node.Name],
   235     version_result: Promise[Document.Version])
   235     version_result: Promise[Document.Version])
   236 
   236 
   237   private val change_parser = Consumer_Thread.fork[Text_Edits]("change_parser", daemon = true)
   237   private val change_parser = Consumer_Thread.fork[Text_Edits]("change_parser", daemon = true)
   238   {
   238   {
   239     case Text_Edits(previous, doc_blobs, text_edits, consolidate, version_result) =>
   239     case Text_Edits(previous, doc_blobs, text_edits, consolidate, version_result) =>
   257     private var commands: Set[Command] = Set.empty
   257     private var commands: Set[Command] = Set.empty
   258 
   258 
   259     def flush(): Unit = synchronized {
   259     def flush(): Unit = synchronized {
   260       if (assignment || nodes.nonEmpty || commands.nonEmpty)
   260       if (assignment || nodes.nonEmpty || commands.nonEmpty)
   261         commands_changed.post(Session.Commands_Changed(assignment, nodes, commands))
   261         commands_changed.post(Session.Commands_Changed(assignment, nodes, commands))
       
   262       if (nodes.nonEmpty) consolidation.update(nodes)
   262       assignment = false
   263       assignment = false
   263       nodes = Set.empty
   264       nodes = Set.empty
   264       commands = Set.empty
   265       commands = Set.empty
   265     }
   266     }
   266     private val delay_flush = Standard_Thread.delay_first(output_delay) { flush() }
   267     private val delay_flush = Standard_Thread.delay_first(output_delay) { flush() }
   297       assigned.reverse
   298       assigned.reverse
   298     }
   299     }
   299   }
   300   }
   300 
   301 
   301 
   302 
       
   303   /* node consolidation */
       
   304 
       
   305   private object consolidation
       
   306   {
       
   307     private val delay =
       
   308       Standard_Thread.delay_first(consolidate_delay) { manager.send(Consolidate_Execution) }
       
   309 
       
   310     private val changed_nodes = Synchronized(Set.empty[Document.Node.Name])
       
   311 
       
   312     def update(new_nodes: Set[Document.Node.Name] = Set.empty)
       
   313     {
       
   314       changed_nodes.change(nodes => if (nodes.isEmpty) new_nodes else nodes ++ new_nodes)
       
   315       delay.invoke()
       
   316     }
       
   317 
       
   318     def flush(): Set[Document.Node.Name] =
       
   319       changed_nodes.change_result(nodes => (nodes, Set.empty))
       
   320 
       
   321     def shutdown() { delay.revoke() }
       
   322   }
       
   323 
       
   324 
   302   /* prover process */
   325   /* prover process */
   303 
   326 
   304   private object prover
   327   private object prover
   305   {
   328   {
   306     private val variable = Synchronized[Option[Prover]](None)
   329     private val variable = Synchronized[Option[Prover]](None)
   345     /* raw edits */
   368     /* raw edits */
   346 
   369 
   347     def handle_raw_edits(
   370     def handle_raw_edits(
   348       doc_blobs: Document.Blobs = Document.Blobs.empty,
   371       doc_blobs: Document.Blobs = Document.Blobs.empty,
   349       edits: List[Document.Edit_Text] = Nil,
   372       edits: List[Document.Edit_Text] = Nil,
   350       consolidate: Boolean = false)
   373       consolidate: List[Document.Node.Name] = Nil)
   351     //{{{
   374     //{{{
   352     {
   375     {
   353       require(prover.defined)
   376       require(prover.defined)
   354 
   377 
   355       prover.get.discontinue_execution()
   378       prover.get.discontinue_execution()
   532               global_state.change(_ => Document.State.init)
   555               global_state.change(_ => Document.State.init)
   533               prover.get.terminate
   556               prover.get.terminate
   534             }
   557             }
   535 
   558 
   536           case Consolidate_Execution =>
   559           case Consolidate_Execution =>
   537             if (prover.defined) handle_raw_edits(consolidate = true)
   560             if (prover.defined) {
       
   561               val state = global_state.value
       
   562               state.stable_tip_version match {
       
   563                 case None => consolidation.update()
       
   564                 case Some(version) =>
       
   565                   val consolidate =
       
   566                     consolidation.flush().iterator.filter(name =>
       
   567                       !resources.session_base.loaded_theory(name) &&
       
   568                       !state.node_consolidated(version, name) &&
       
   569                       state.node_maybe_consolidated(version, name)).toList
       
   570                   if (consolidate.nonEmpty) handle_raw_edits(consolidate = consolidate)
       
   571               }
       
   572             }
   538 
   573 
   539           case Prune_History =>
   574           case Prune_History =>
   540             if (prover.defined) {
   575             if (prover.defined) {
   541               val old_versions = global_state.change_result(_.remove_versions(prune_size))
   576               val old_versions = global_state.change_result(_.remove_versions(prune_size))
   542               if (old_versions.nonEmpty) prover.get.remove_versions(old_versions)
   577               if (old_versions.nonEmpty) prover.get.remove_versions(old_versions)
   578         }
   613         }
   579         true
   614         true
   580         //}}}
   615         //}}}
   581     }
   616     }
   582   }
   617   }
   583 
       
   584   private val consolidator: Thread =
       
   585     Standard_Thread.fork("Session.consolidator", daemon = true) {
       
   586       try {
       
   587         while (true) {
       
   588           Thread.sleep(consolidate_delay.ms)
       
   589 
       
   590           val state = global_state.value
       
   591           state.stable_tip_version match {
       
   592             case None =>
       
   593             case Some(version) =>
       
   594               val consolidated =
       
   595                 version.nodes.iterator.forall(
       
   596                   { case (name, _) =>
       
   597                       resources.session_base.loaded_theory(name) ||
       
   598                       state.node_consolidated(version, name) })
       
   599               if (!consolidated) manager.send(Consolidate_Execution)
       
   600           }
       
   601         }
       
   602       }
       
   603       catch { case Exn.Interrupt() => }
       
   604     }
       
   605 
   618 
   606 
   619 
   607   /* main operations */
   620   /* main operations */
   608 
   621 
   609   def snapshot(name: Document.Node.Name = Document.Node.Name.empty,
   622   def snapshot(name: Document.Node.Name = Document.Node.Name.empty,
   639     send_stop()
   652     send_stop()
   640     prover.await_reset()
   653     prover.await_reset()
   641 
   654 
   642     change_parser.shutdown()
   655     change_parser.shutdown()
   643     change_buffer.shutdown()
   656     change_buffer.shutdown()
   644     consolidator.interrupt
   657     consolidation.shutdown()
   645     consolidator.join
       
   646     manager.shutdown()
   658     manager.shutdown()
   647     dispatcher.shutdown()
   659     dispatcher.shutdown()
   648 
   660 
   649     phase match {
   661     phase match {
   650       case Session.Terminated(result) => result
   662       case Session.Terminated(result) => result