356 Build_Session_Errors.result |
356 Build_Session_Errors.result |
357 case Exn.Exn(exn) => Exn.Res(List(Exn.message(exn))) |
357 case Exn.Exn(exn) => Exn.Res(List(Exn.message(exn))) |
358 } |
358 } |
359 } |
359 } |
360 |
360 |
361 val process_result = |
361 val result0 = |
362 Isabelle_Thread.interrupt_handler(_ => process.terminate()) { process.await_shutdown() } |
362 Isabelle_Thread.interrupt_handler(_ => process.terminate()) { process.await_shutdown() } |
363 |
363 |
364 session.stop() |
364 session.stop() |
365 |
365 |
366 val export_errors = |
366 val export_errors = |
367 export_consumer.shutdown(close = true).map(Output.error_message_text) |
367 export_consumer.shutdown(close = true).map(Output.error_message_text) |
368 |
368 |
369 val (document_output, document_errors) = |
369 val (document_output, document_errors) = |
370 try { |
370 try { |
371 if (build_errors.isInstanceOf[Exn.Res[_]] && process_result.ok && info.documents.nonEmpty) { |
371 if (build_errors.isInstanceOf[Exn.Res[_]] && result0.ok && info.documents.nonEmpty) { |
372 using(Export.open_database_context(store)) { database_context => |
372 using(Export.open_database_context(store)) { database_context => |
373 val documents = |
373 val documents = |
374 using(database_context.open_session(session_background)) { |
374 using(database_context.open_session(session_background)) { |
375 session_context => |
375 session_context => |
376 Document_Build.build_documents( |
376 Document_Build.build_documents( |
388 catch { |
388 catch { |
389 case exn: Document_Build.Build_Error => (exn.log_lines, exn.log_errors) |
389 case exn: Document_Build.Build_Error => (exn.log_lines, exn.log_errors) |
390 case Exn.Interrupt.ERROR(msg) => (Nil, List(msg)) |
390 case Exn.Interrupt.ERROR(msg) => (Nil, List(msg)) |
391 } |
391 } |
392 |
392 |
393 val result = { |
393 val result1 = { |
394 val theory_timing = |
394 val theory_timing = |
395 theory_timings.iterator.flatMap( |
395 theory_timings.iterator.flatMap( |
396 { |
396 { |
397 case props @ Markup.Name(name) => Some(name -> props) |
397 case props @ Markup.Name(name) => Some(name -> props) |
398 case _ => None |
398 case _ => None |
408 session_timings.toList.map(Protocol.Session_Timing_Marker.apply) ::: |
408 session_timings.toList.map(Protocol.Session_Timing_Marker.apply) ::: |
409 runtime_statistics.toList.map(Protocol.ML_Statistics_Marker.apply) ::: |
409 runtime_statistics.toList.map(Protocol.ML_Statistics_Marker.apply) ::: |
410 task_statistics.toList.map(Protocol.Task_Statistics_Marker.apply) ::: |
410 task_statistics.toList.map(Protocol.Task_Statistics_Marker.apply) ::: |
411 document_output |
411 document_output |
412 |
412 |
413 process_result.output(more_output) |
413 result0.output(more_output) |
414 .error(Library.trim_line(stderr.toString)) |
414 .error(Library.trim_line(stderr.toString)) |
415 .errors_rc(export_errors ::: document_errors) |
415 .errors_rc(export_errors ::: document_errors) |
416 } |
416 } |
417 |
417 |
418 build_errors match { |
418 val result2 = |
419 case Exn.Res(build_errs) => |
419 build_errors match { |
420 val errs = build_errs ::: document_errors |
420 case Exn.Res(build_errs) => |
421 if (errs.nonEmpty) { |
421 val errs = build_errs ::: document_errors |
422 result.error_rc.output( |
422 if (errs.nonEmpty) { |
423 errs.flatMap(s => split_lines(Output.error_message_text(s))) ::: |
423 result1.error_rc.output( |
424 errs.map(Protocol.Error_Message_Marker.apply)) |
424 errs.flatMap(s => split_lines(Output.error_message_text(s))) ::: |
425 } |
425 errs.map(Protocol.Error_Message_Marker.apply)) |
426 else if (progress.stopped && result.ok) result.copy(rc = Process_Result.RC.interrupt) |
426 } |
427 else result |
427 else if (progress.stopped && result1.ok) result1.copy(rc = Process_Result.RC.interrupt) |
428 case Exn.Exn(Exn.Interrupt()) => |
428 else result1 |
429 if (result.ok) result.copy(rc = Process_Result.RC.interrupt) |
429 case Exn.Exn(Exn.Interrupt()) => |
430 else result |
430 if (result1.ok) result1.copy(rc = Process_Result.RC.interrupt) |
431 case Exn.Exn(exn) => throw exn |
431 else result1 |
432 } |
432 case Exn.Exn(exn) => throw exn |
|
433 } |
|
434 |
|
435 result2 |
433 } |
436 } |
434 |
437 |
435 override def terminate(): Unit = future_result.cancel() |
438 override def terminate(): Unit = future_result.cancel() |
436 override def is_finished: Boolean = future_result.is_finished |
439 override def is_finished: Boolean = future_result.is_finished |
437 |
440 |
440 else Some(Event_Timer.request(Time.now() + info.timeout) { terminate() }) |
443 else Some(Event_Timer.request(Time.now() + info.timeout) { terminate() }) |
441 } |
444 } |
442 |
445 |
443 override lazy val finish: (Process_Result, SHA1.Shasum) = { |
446 override lazy val finish: (Process_Result, SHA1.Shasum) = { |
444 val process_result = { |
447 val process_result = { |
445 val result = future_result.join |
448 val result2 = future_result.join |
446 |
449 |
447 val was_timeout = |
450 val was_timeout = |
448 timeout_request match { |
451 timeout_request match { |
449 case None => false |
452 case None => false |
450 case Some(request) => !request.cancel() |
453 case Some(request) => !request.cancel() |
451 } |
454 } |
452 |
455 |
453 if (result.ok) result |
456 if (result2.ok) result2 |
454 else if (was_timeout) result.error(Output.error_message_text("Timeout")).timeout_rc |
457 else if (was_timeout) result2.error(Output.error_message_text("Timeout")).timeout_rc |
455 else if (result.interrupted) result.error(Output.error_message_text("Interrupt")) |
458 else if (result2.interrupted) result2.error(Output.error_message_text("Interrupt")) |
456 else result |
459 else result2 |
457 } |
460 } |
458 |
461 |
459 val output_shasum = |
462 val output_shasum = |
460 if (process_result.ok && store_heap && store.output_heap(session_name).is_file) { |
463 if (process_result.ok && store_heap && store.output_heap(session_name).is_file) { |
461 SHA1.shasum(ML_Heap.write_digest(store.output_heap(session_name)), session_name) |
464 SHA1.shasum(ML_Heap.write_digest(store.output_heap(session_name)), session_name) |