| -- C940016.A |
| -- |
| -- Grant of Unlimited Rights |
| -- |
| -- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687, |
| -- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained |
| -- unlimited rights in the software and documentation contained herein. |
| -- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making |
| -- this public release, the Government intends to confer upon all |
| -- recipients unlimited rights equal to those held by the Government. |
| -- These rights include rights to use, duplicate, release or disclose the |
| -- released technical data and computer software in whole or in part, in |
| -- any manner and for any purpose whatsoever, and to have or permit others |
| -- to do so. |
| -- |
| -- DISCLAIMER |
| -- |
| -- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR |
| -- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED |
| -- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE |
| -- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE |
| -- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A |
| -- PARTICULAR PURPOSE OF SAID MATERIAL. |
| --* |
| -- |
| -- TEST OBJECTIVE: |
| -- Check that an Unchecked_Deallocation of a protected object |
| -- performs the required finalization on the protected object. |
| -- |
| -- TEST DESCRIPTION: |
| -- Test that finalization takes place when an Unchecked_Deallocation |
| -- deallocates a protected object with queued callers. |
| -- Try protected objects that have no other finalization code and |
| -- protected objects with user defined finalization. |
| -- |
| -- |
| -- CHANGE HISTORY: |
| -- 16 Jan 96 SAIC ACVC 2.1 |
| -- 10 Jul 96 SAIC Fixed race condition noted by reviewers. |
| -- |
| --! |
| |
| |
| with Ada.Finalization; |
| package C940016_0 is |
| Verbose : constant Boolean := False; |
| Finalization_Occurred : Boolean := False; |
| |
| type Has_Finalization is new Ada.Finalization.Limited_Controlled with |
| record |
| Placeholder : Integer; |
| end record; |
| procedure Finalize (Object : in out Has_Finalization); |
| end C940016_0; |
| |
| |
| with Report; |
| with ImpDef; |
| package body C940016_0 is |
| procedure Finalize (Object : in out Has_Finalization) is |
| begin |
| delay ImpDef.Clear_Ready_Queue; |
| Finalization_Occurred := True; |
| if Verbose then |
| Report.Comment ("in Finalize"); |
| end if; |
| end Finalize; |
| end C940016_0; |
| |
| |
| |
| with Report; |
| with Ada.Finalization; |
| with C940016_0; |
| with Ada.Unchecked_Deallocation; |
| with ImpDef; |
| |
| procedure C940016 is |
| Verbose : constant Boolean := C940016_0.Verbose; |
| |
| begin |
| |
| Report.Test ("C940016", "Check that Unchecked_Deallocation of a" & |
| " protected object finalizes the" & |
| " protected object"); |
| |
| First_Check: declare |
| protected type Semaphore is |
| entry Wait; |
| procedure Signal; |
| private |
| Count : Integer := 0; |
| end Semaphore; |
| protected body Semaphore is |
| entry Wait when Count > 0 is |
| begin |
| Count := Count - 1; |
| end Wait; |
| |
| procedure Signal is |
| begin |
| Count := Count + 1; |
| end Signal; |
| end Semaphore; |
| |
| type pSem is access Semaphore; |
| procedure Zap_Semaphore is new |
| Ada.Unchecked_Deallocation (Semaphore, pSem); |
| Sem_Ptr : pSem := new Semaphore; |
| |
| -- positive confirmation that Blocker got the exception |
| Ok : Boolean := False; |
| |
| task Blocker; |
| |
| task body Blocker is |
| begin |
| Sem_Ptr.Wait; |
| Report.Failed ("Program_Error not raised in waiting task"); |
| exception |
| when Program_Error => |
| Ok := True; |
| if Verbose then |
| Report.Comment ("Blocker received Program_Error"); |
| end if; |
| when others => |
| Report.Failed ("Wrong exception in Blocker"); |
| end Blocker; |
| |
| begin -- First_Check |
| -- wait for Blocker to get blocked on the semaphore |
| delay ImpDef.Clear_Ready_Queue; |
| Zap_Semaphore (Sem_Ptr); |
| -- make sure Blocker has time to complete |
| delay ImpDef.Clear_Ready_Queue * 2; |
| if not Ok then |
| Report.Failed ("finalization not properly performed"); |
| -- Blocker is probably hung so kill it |
| abort Blocker; |
| end if; |
| end First_Check; |
| |
| |
| Second_Check : declare |
| -- here we want to check that the raising of Program_Error |
| -- occurs before the other finalization actions. |
| protected type Semaphore is |
| entry Wait; |
| procedure Signal; |
| private |
| Count : Integer := 0; |
| Component : C940016_0.Has_Finalization; |
| end Semaphore; |
| protected body Semaphore is |
| entry Wait when Count > 0 is |
| begin |
| Count := Count - 1; |
| end Wait; |
| |
| procedure Signal is |
| begin |
| Count := Count + 1; |
| end Signal; |
| end Semaphore; |
| |
| type pSem is access Semaphore; |
| procedure Zap_Semaphore is new |
| Ada.Unchecked_Deallocation (Semaphore, pSem); |
| Sem_Ptr : pSem := new Semaphore; |
| |
| -- positive confirmation that Blocker got the exception |
| Ok : Boolean := False; |
| |
| task Blocker; |
| |
| task body Blocker is |
| begin |
| Sem_Ptr.Wait; |
| Report.Failed ("Program_Error not raised in waiting task 2"); |
| exception |
| when Program_Error => |
| Ok := True; |
| if C940016_0.Finalization_Occurred then |
| Report.Failed ("wrong order for finalization 2"); |
| elsif Verbose then |
| Report.Comment ("Blocker received Program_Error 2"); |
| end if; |
| when others => |
| Report.Failed ("Wrong exception in Blocker 2"); |
| end Blocker; |
| |
| begin -- Second_Check |
| -- wait for Blocker to get blocked on the semaphore |
| delay ImpDef.Clear_Ready_Queue; |
| Zap_Semaphore (Sem_Ptr); |
| -- make sure Blocker has time to complete |
| delay ImpDef.Clear_Ready_Queue * 2; |
| if not Ok then |
| Report.Failed ("finalization not properly performed 2"); |
| -- Blocker is probably hung so kill it |
| abort Blocker; |
| end if; |
| if not C940016_0.Finalization_Occurred then |
| Report.Failed ("user defined finalization didn't happen"); |
| end if; |
| end Second_Check; |
| |
| |
| Report.Result; |
| |
| end C940016; |