src/Pure/System/build.scala
changeset 48661 9149ebdd0241
parent 48660 730ca503e955
child 48671 951bc4c3ee17
equal deleted inserted replaced
48660:730ca503e955 48661:9149ebdd0241
     5 */
     5 */
     6 
     6 
     7 package isabelle
     7 package isabelle
     8 
     8 
     9 
     9 
       
    10 import java.util.{Timer, TimerTask}
    10 import java.io.{BufferedInputStream, FileInputStream,
    11 import java.io.{BufferedInputStream, FileInputStream,
    11   BufferedReader, InputStreamReader, IOException}
    12   BufferedReader, InputStreamReader, IOException}
    12 import java.util.zip.GZIPInputStream
    13 import java.util.zip.GZIPInputStream
    13 
    14 
    14 import scala.collection.mutable
    15 import scala.collection.mutable
   329 
   330 
   330 
   331 
   331   /* jobs */
   332   /* jobs */
   332 
   333 
   333   private class Job(dir: Path, env: Map[String, String], script: String, args: String,
   334   private class Job(dir: Path, env: Map[String, String], script: String, args: String,
   334     val parent_heap: String, output: Path, do_output: Boolean)
   335     val parent_heap: String, output: Path, do_output: Boolean, time: Time)
   335   {
   336   {
   336     private val args_file = File.tmp_file("args")
   337     private val args_file = File.tmp_file("args")
   337     private val env1 = env + ("ARGS_FILE" -> Isabelle_System.posix_path(args_file.getPath))
   338     private val env1 = env + ("ARGS_FILE" -> Isabelle_System.posix_path(args_file.getPath))
   338     File.write(args_file, args)
   339     File.write(args_file, args)
   339 
   340 
   340     private val (thread, result) =
   341     private val (thread, result) =
   341       Simple_Thread.future("build") { Isabelle_System.bash_env(dir.file, env1, script) }
   342       Simple_Thread.future("build") { Isabelle_System.bash_env(dir.file, env1, script) }
   342 
   343 
   343     def terminate: Unit = thread.interrupt
   344     def terminate: Unit = thread.interrupt
   344     def is_finished: Boolean = result.is_finished
   345     def is_finished: Boolean = result.is_finished
   345     def join: (String, String, Int) = { val res = result.join; args_file.delete; res }
   346 
       
   347     @volatile private var timeout = false
       
   348     private val timer: Option[Timer] =
       
   349       if (time.seconds > 0.0) {
       
   350         val t = new Timer("build", true)
       
   351         t.schedule(new TimerTask { def run = { terminate; timeout = true } }, time.ms)
       
   352         Some(t)
       
   353       }
       
   354       else None
       
   355 
       
   356     def join: (String, String, Int) = {
       
   357       val (out, err, rc) = result.join
       
   358       args_file.delete
       
   359       timer.map(_.cancel())
       
   360 
       
   361       val err1 =
       
   362         if (rc == 130)
       
   363           (if (err.isEmpty || err.endsWith("\n")) err else err + "\n") +
       
   364           (if (timeout) "*** Timeout\n" else "*** Interrupt\n")
       
   365         else err
       
   366       (out, err1, rc)
       
   367     }
       
   368 
   346     def output_path: Option[Path] = if (do_output) Some(output) else None
   369     def output_path: Option[Path] = if (do_output) Some(output) else None
   347   }
   370   }
   348 
   371 
   349   private def start_job(name: String, info: Session.Info, parent_heap: String,
   372   private def start_job(name: String, info: Session.Info, parent_heap: String,
   350     output: Path, do_output: Boolean, options: Options, verbose: Boolean, browser_info: Path): Job =
   373     output: Path, do_output: Boolean, options: Options, verbose: Boolean, browser_info: Path): Job =
   400           pair(bool, pair(Options.encode, pair(bool, pair(Path.encode, pair(string,
   423           pair(bool, pair(Options.encode, pair(bool, pair(Path.encode, pair(string,
   401             pair(string, list(pair(Options.encode, list(Path.encode)))))))))(
   424             pair(string, list(pair(Options.encode, list(Path.encode)))))))))(
   402           (do_output, (options, (verbose, (browser_info, (parent,
   425           (do_output, (options, (verbose, (browser_info, (parent,
   403             (name, info.theories)))))))
   426             (name, info.theories)))))))
   404     }
   427     }
   405     new Job(info.dir, env, script, YXML.string_of_body(args_xml), parent_heap, output, do_output)
   428     new Job(info.dir, env, script, YXML.string_of_body(args_xml), parent_heap,
       
   429       output, do_output, Time.seconds(options.real("timeout")))
   406   }
   430   }
   407 
   431 
   408 
   432 
   409   /* log files and corresponding heaps */
   433   /* log files and corresponding heaps */
   410 
   434 
   523                 (output_dir + Path.basic(name)).file.delete
   547                 (output_dir + Path.basic(name)).file.delete
   524                 (output_dir + log_gz(name)).file.delete
   548                 (output_dir + log_gz(name)).file.delete
   525 
   549 
   526                 File.write(output_dir + log(name), out)
   550                 File.write(output_dir + log(name), out)
   527                 echo(name + " FAILED")
   551                 echo(name + " FAILED")
   528                 echo("(see also " + (output_dir + log(name)).file.toString + ")")
   552                 if (rc != 130) {
   529                 val lines = split_lines(out)
   553                   echo("(see also " + (output_dir + log(name)).file.toString + ")")
   530                 val tail = lines.drop(lines.length - 20 max 0)
   554                   val lines = split_lines(out)
   531                 echo("\n" + cat_lines(tail))
   555                   val tail = lines.drop(lines.length - 20 max 0)
       
   556                   echo("\n" + cat_lines(tail))
       
   557                 }
   532 
   558 
   533                 no_heap
   559                 no_heap
   534               }
   560               }
   535             loop(pending - name, running - name, results + (name -> Result(false, heap, rc)))
   561             loop(pending - name, running - name, results + (name -> Result(false, heap, rc)))
   536 
   562