@@ -285,7 +285,8 @@ declares two protected procedures. Both match the profile specified by type
285
285
:ada: `Termination_Handler `. One such procedure would suffice, we just provide
286
286
two for the sake of illustrating the flexibility of the dynamic approach.
287
287
288
- .. code-block :: ada
288
+ .. code :: ada no_button project=Courses.Ada_In_Practice.Silent_Task_Termination.Obituary
289
+ :class: ada-syntax-only
289
290
290
291
with Ada.Exceptions; use Ada.Exceptions;
291
292
with Ada.Task_Termination; use Ada.Task_Termination;
@@ -296,15 +297,15 @@ two for the sake of illustrating the flexibility of the dynamic approach.
296
297
protected Writer is
297
298
298
299
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);
302
303
-- Written by someone who's read too much English lit
303
304
304
305
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);
308
309
-- Written by someone who may know more than they're saying
309
310
310
311
end Writer;
@@ -359,46 +360,59 @@ The observant reader will note the with-clause for :ada:`Ada.Text_IO`,
359
360
included for the sake of references to :ada: `Put_Line `. We'll address the
360
361
ramifications momentarily. Here are the bodies for the two handlers:
361
362
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;
363
415
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;
402
416
403
417
Now, about those calls to :ada: `Ada.Text_IO.Put_Line `. Because of those calls,
404
418
the bodies of procedures :ada: `Note_Passing ` and :ada: `Dissemble ` are not
@@ -422,14 +436,16 @@ to print the announcement with those values.
422
436
423
437
Here's the updated :ada: `Obituary ` package declaration:
424
438
425
- .. code-block :: ada
439
+ .. code :: ada no_button project=Courses.Ada_In_Practice.Silent_Task_Termination.Obituary_Updated
440
+ :class: ada-syntax-only
426
441
427
442
with Ada.Exceptions; use Ada.Exceptions;
428
443
with Ada.Task_Termination; use Ada.Task_Termination;
429
444
with Ada.Task_Identification; use Ada.Task_Identification;
430
445
with Ada.Containers.Vectors;
431
446
432
447
package Obituary is
448
+
433
449
pragma Elaborate_Body;
434
450
435
451
Comment_On_Normal_Passing : Boolean := True;
@@ -447,9 +463,9 @@ Here's the updated :ada:`Obituary` package declaration:
447
463
protected Writer is
448
464
449
465
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);
453
469
454
470
entry Get_Event (Next : out Termination_Event);
455
471
@@ -469,7 +485,7 @@ artifact.
469
485
470
486
The updated package body is straightforward:
471
487
472
- .. code-block :: ada
488
+ .. code :: ada compile_button project=Courses.Ada_In_Practice.Silent_Task_Termination.Obituary_Updated
473
489
474
490
package body Obituary is
475
491
@@ -480,9 +496,9 @@ The updated package body is straightforward:
480
496
------------------
481
497
482
498
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)
486
502
is
487
503
begin
488
504
if Cause = Normal and then
@@ -518,7 +534,8 @@ The updated package body is straightforward:
518
534
519
535
A new child package declares the task that prints the termination information:
520
536
521
- .. code-block :: ada
537
+ .. code :: ada no_button project=Courses.Ada_In_Practice.Silent_Task_Termination.Obituary_Updated
538
+ :class: ada-syntax-only
522
539
523
540
package Obituary.Output is
524
541
pragma Elaborate_Body;
@@ -532,7 +549,7 @@ In the package body, the task body iteratively suspends on the call to
532
549
termination data available. Once it returns from the call, if ever, it simply
533
550
prints the information and awaits further events:
534
551
535
- .. code-block :: ada
552
+ .. code :: ada compile_button project=Courses.Ada_In_Practice.Silent_Task_Termination.Obituary_Updated
536
553
537
554
with Ada.Text_IO; use Ada.Text_IO;
538
555
@@ -549,15 +566,15 @@ prints the information and awaits further events:
549
566
Writer. Get_Event (Next);
550
567
case Next.Cause is
551
568
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!
554
571
Put_Line ("We had nothing to do with it.");
555
572
when Abnormal =>
556
- Put_Line (Image(Next.Departed) &
573
+ Put_Line (Image (Next.Departed) &
557
574
" had a terrible accident.");
558
575
Put_Line ("We're sorry it had to come to that.");
559
576
when Unhandled_Exception =>
560
- Put_Line (Image(Next.Departed) &
577
+ Put_Line (Image (Next.Departed) &
561
578
" reacted badly to " &
562
579
Exception_Name (Next.Event));
563
580
Put_Line ("Really, really badly.");
@@ -576,7 +593,8 @@ retrieve the information stored by the protected :ada:`Writer` object.
576
593
Here is a sample demonstration main procedure, a simple test to ensure that
577
594
termination due to task abort is captured and displayed:
578
595
579
- .. code-block :: ada
596
+ .. code :: ada run_button project=Courses.Ada_In_Practice.Silent_Task_Termination.Obituary_Updated
597
+ :class: ada-norun
580
598
581
599
with Obituary.Output; pragma Unreferenced (Obituary.Output);
582
600
-- otherwise neither package is in the executable
@@ -586,8 +604,8 @@ termination due to task abort is captured and displayed:
586
604
task Worker;
587
605
task body Worker is
588
606
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
591
609
end loop;
592
610
end Worker;
593
611
@@ -651,7 +669,8 @@ Notes
651
669
If you did want to use a generic package to define a task type that is
652
670
resilient to unhandled exceptions, you could do it like this:
653
671
654
- .. code-block :: ada
672
+ .. code :: ada no_button project=Courses.Ada_In_Practice.Silent_Task_Termination.Resilient_Workers
673
+ :class: ada-syntax-only
655
674
656
675
with System;
657
676
with Ada.Exceptions; use Ada.Exceptions;
@@ -715,7 +734,7 @@ initialization, called only once with mode out for the state, and one for
715
734
partial initialization, called on each iteration of the :ada: `Recovery ` loop
716
735
with mode in-out for the state:
717
736
718
- .. code-block :: ada
737
+ .. code :: ada compile_button project=Courses.Ada_In_Practice.Silent_Task_Termination.Resilient_Workers
719
738
720
739
task body Worker is
721
740
State : Task_Local_State;
0 commit comments