@@ -285,7 +285,8 @@ declares two protected procedures. Both match the profile specified by type
285285:ada: `Termination_Handler `. One such procedure would suffice, we just provide
286286two for the sake of illustrating the flexibility of the dynamic approach.
287287
288- .. code-block :: ada
288+ .. code :: ada no_button project=Courses.Ada_In_Practice.Silent_Task_Termination.Obituary
289+ :class: ada-syntax-only
289290
290291 with Ada.Exceptions; use Ada.Exceptions;
291292 with Ada.Task_Termination; use Ada.Task_Termination;
@@ -296,15 +297,15 @@ two for the sake of illustrating the flexibility of the dynamic approach.
296297 protected Writer is
297298
298299 procedure Note_Passing
299- (Cause : in Cause_Of_Termination;
300- Departed : in Task_Id;
301- Event : in Exception_Occurrence);
300+ (Cause : Cause_Of_Termination;
301+ Departed : Task_Id;
302+ Event : Exception_Occurrence);
302303 -- Written by someone who's read too much English lit
303304
304305 procedure Dissemble
305- (Cause : in Cause_Of_Termination;
306- Departed : in Task_Id;
307- Event : in Exception_Occurrence);
306+ (Cause : Cause_Of_Termination;
307+ Departed : Task_Id;
308+ Event : Exception_Occurrence);
308309 -- Written by someone who may know more than they're saying
309310
310311 end Writer;
@@ -359,46 +360,59 @@ The observant reader will note the with-clause for :ada:`Ada.Text_IO`,
359360included for the sake of references to :ada: `Put_Line `. We'll address the
360361ramifications momentarily. Here are the bodies for the two handlers:
361362
362- .. code-block :: ada
363+ .. code :: ada compile_button project=Courses.Ada_In_Practice.Silent_Task_Termination.Obituary
364+
365+ with Ada.Text_IO; use Ada.Text_IO;
366+
367+ package body Obituary is
368+
369+ protected body Writer is
370+
371+ procedure Note_Passing
372+ (Cause : Cause_Of_Termination;
373+ Departed : Task_Id;
374+ Event : Exception_Occurrence)
375+ is
376+ begin
377+ case Cause is
378+ when Normal =>
379+ Put_Line (Image (Departed) &
380+ " went gently into that good night");
381+ when Abnormal =>
382+ Put_Line (Image (Departed) & " was most fouly murdered!");
383+ when Unhandled_Exception =>
384+ Put_Line (Image (Departed) &
385+ " was unknit by the much unexpected " &
386+ Exception_Name (Event));
387+ end case;
388+ end Note_Passing;
389+
390+ procedure Dissemble
391+ (Cause : Cause_Of_Termination;
392+ Departed : Task_Id;
393+ Event : Exception_Occurrence)
394+ is
395+ begin
396+ case Cause is
397+ when Normal =>
398+ Put_Line (Image (Departed) & " died, naturally.");
399+ Put_Line ("We had nothing to do with it.");
400+ when Abnormal =>
401+ Put_Line (Image (Departed) & " had a tragic accident.");
402+ Put_Line ("We're sorry it had to come to that.");
403+ when Unhandled_Exception =>
404+ Put_Line (Image (Departed) &
405+ " was apparently fatally allergic to " &
406+ Exception_Name (Event));
407+ end case;
408+ end Dissemble;
409+
410+ end Writer;
411+
412+ begin -- optional package executable part
413+ Set_Dependents_Fallback_Handler (Writer.Note_Passing'Access);
414+ end Obituary;
363415
364- procedure Note_Passing
365- (Cause : in Cause_Of_Termination;
366- Departed : in Task_Id;
367- Event : in Exception_Occurrence)
368- is
369- begin
370- case Cause is
371- when Normal =>
372- Put_Line (Image (Departed) &
373- " went gently into that good night");
374- when Abnormal =>
375- Put_Line (Image (Departed) & " was most fouly murdered!");
376- when Unhandled_Exception =>
377- Put_Line (Image (Departed) &
378- " was unknit by the much unexpected " &
379- Exception_Name (Event));
380- end case;
381- end Note_Passing;
382-
383- procedure Dissemble
384- (Cause : in Cause_Of_Termination;
385- Departed : in Task_Id;
386- Event : in Exception_Occurrence)
387- is
388- begin
389- case Cause is
390- when Normal =>
391- Put_Line (Image (Departed) & " died, naturally.");
392- Put_Line ("We had nothing to do with it.");
393- when Abnormal =>
394- Put_Line (Image (Departed) & " had a tragic accident.");
395- Put_Line ("We're sorry it had to come to that.");
396- when Unhandled_Exception =>
397- Put_Line (Image (Departed) &
398- " was apparently fatally allergic to " &
399- Exception_Name (Event));
400- end case;
401- end Dissemble;
402416
403417Now, about those calls to :ada: `Ada.Text_IO.Put_Line `. Because of those calls,
404418the bodies of procedures :ada: `Note_Passing ` and :ada: `Dissemble ` are not
@@ -422,14 +436,16 @@ to print the announcement with those values.
422436
423437Here's the updated :ada: `Obituary ` package declaration:
424438
425- .. code-block :: ada
439+ .. code :: ada no_button project=Courses.Ada_In_Practice.Silent_Task_Termination.Obituary_Updated
440+ :class: ada-syntax-only
426441
427442 with Ada.Exceptions; use Ada.Exceptions;
428443 with Ada.Task_Termination; use Ada.Task_Termination;
429444 with Ada.Task_Identification; use Ada.Task_Identification;
430445 with Ada.Containers.Vectors;
431446
432447 package Obituary is
448+
433449 pragma Elaborate_Body;
434450
435451 Comment_On_Normal_Passing : Boolean := True;
@@ -447,9 +463,9 @@ Here's the updated :ada:`Obituary` package declaration:
447463 protected Writer is
448464
449465 procedure Note_Passing
450- (Cause : in Cause_Of_Termination;
451- Departed : in Task_Id;
452- Event : in Exception_Occurrence);
466+ (Cause : Cause_Of_Termination;
467+ Departed : Task_Id;
468+ Event : Exception_Occurrence);
453469
454470 entry Get_Event (Next : out Termination_Event);
455471
@@ -469,7 +485,7 @@ artifact.
469485
470486The updated package body is straightforward:
471487
472- .. code-block :: ada
488+ .. code :: ada compile_button project=Courses.Ada_In_Practice.Silent_Task_Termination.Obituary_Updated
473489
474490 package body Obituary is
475491
@@ -480,9 +496,9 @@ The updated package body is straightforward:
480496 ------------------
481497
482498 procedure Note_Passing
483- (Cause : in Cause_Of_Termination;
484- Departed : in Task_Id;
485- Event : in Exception_Occurrence)
499+ (Cause : Cause_Of_Termination;
500+ Departed : Task_Id;
501+ Event : Exception_Occurrence)
486502 is
487503 begin
488504 if Cause = Normal and then
@@ -518,7 +534,8 @@ The updated package body is straightforward:
518534
519535A new child package declares the task that prints the termination information:
520536
521- .. code-block :: ada
537+ .. code :: ada no_button project=Courses.Ada_In_Practice.Silent_Task_Termination.Obituary_Updated
538+ :class: ada-syntax-only
522539
523540 package Obituary.Output is
524541 pragma Elaborate_Body;
@@ -532,7 +549,7 @@ In the package body, the task body iteratively suspends on the call to
532549termination data available. Once it returns from the call, if ever, it simply
533550prints the information and awaits further events:
534551
535- .. code-block :: ada
552+ .. code :: ada compile_button project=Courses.Ada_In_Practice.Silent_Task_Termination.Obituary_Updated
536553
537554 with Ada.Text_IO; use Ada.Text_IO;
538555
@@ -549,15 +566,15 @@ prints the information and awaits further events:
549566 Writer. Get_Event (Next);
550567 case Next.Cause is
551568 when Normal =>
552- Put_Line (Image(Next.Departed) & " died, naturally.");
553- -- What a difference that comma makes!
569+ Put_Line (Image (Next.Departed) & " died, naturally.");
570+ -- What a difference that comma makes!
554571 Put_Line ("We had nothing to do with it.");
555572 when Abnormal =>
556- Put_Line (Image(Next.Departed) &
573+ Put_Line (Image (Next.Departed) &
557574 " had a terrible accident.");
558575 Put_Line ("We're sorry it had to come to that.");
559576 when Unhandled_Exception =>
560- Put_Line (Image(Next.Departed) &
577+ Put_Line (Image (Next.Departed) &
561578 " reacted badly to " &
562579 Exception_Name (Next.Event));
563580 Put_Line ("Really, really badly.");
@@ -576,7 +593,8 @@ retrieve the information stored by the protected :ada:`Writer` object.
576593Here is a sample demonstration main procedure, a simple test to ensure that
577594termination due to task abort is captured and displayed:
578595
579- .. code-block :: ada
596+ .. code :: ada run_button project=Courses.Ada_In_Practice.Silent_Task_Termination.Obituary_Updated
597+ :class: ada-norun
580598
581599 with Obituary.Output; pragma Unreferenced (Obituary.Output);
582600 -- otherwise neither package is in the executable
@@ -586,8 +604,8 @@ termination due to task abort is captured and displayed:
586604 task Worker;
587605 task body Worker is
588606 begin
589- loop -- ensure not already terminated when aborted
590- delay 0.0; -- yield the processor
607+ loop -- ensure not already terminated when aborted
608+ delay 0.0; -- yield the processor
591609 end loop;
592610 end Worker;
593611
@@ -651,7 +669,7 @@ Notes
651669If you did want to use a generic package to define a task type that is
652670resilient to unhandled exceptions, you could do it like this:
653671
654- .. code-block :: ada
672+ .. code :: ada compile_button project=Courses.Ada_In_Practice.Silent_Task_Termination.Resilient_Workers
655673
656674 with System;
657675 with Ada.Exceptions; use Ada.Exceptions;
@@ -672,7 +690,6 @@ resilient to unhandled exceptions, you could do it like this:
672690
673691 end Resilient_Workers;
674692
675-
676693 package body Resilient_Workers is
677694
678695 task body Worker is
@@ -715,7 +732,9 @@ initialization, called only once with mode out for the state, and one for
715732partial initialization, called on each iteration of the :ada: `Recovery ` loop
716733with mode in-out for the state:
717734
718- .. code-block :: ada
735+ .. code :: ada compile_button project=Courses.Ada_In_Practice.Silent_Task_Termination.Resilient_Workers
736+
737+ package body Resilient_Workers is
719738
720739 task body Worker is
721740 State : Task_Local_State;
@@ -726,7 +745,7 @@ with mode in-out for the state:
726745 begin
727746 Normal : loop
728747 Update (State);
729- -- The call above is expected to return, ie
748+ -- The call above is expected to return, i.e.
730749 -- this loop is meant to iterate
731750 end loop Normal;
732751 exception
@@ -738,6 +757,8 @@ with mode in-out for the state:
738757 end loop Recovery;
739758 end Worker;
740759
760+ end Resilient_Workers;
761+
741762If both application initialization routines happen to do the same thing, we'd
742763like the developer to be able to pass the same application procedure to both
743764generic formal procedures :ada: `Fully_Initialize ` and
0 commit comments