blob: 2226eefb40df4eaaf6611949b08702981d8c7ac6 [file] [log] [blame]
-- 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;