From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,ee06257af909a235 X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII Path: g2news1.google.com!postnews.google.com!e65g2000hsc.googlegroups.com!not-for-mail From: Adam Beneschan Newsgroups: comp.lang.ada Subject: Re: Finalization of static package variables Date: 9 May 2007 16:27:08 -0700 Organization: http://groups.google.com Message-ID: <1178753228.648765.89390@e65g2000hsc.googlegroups.com> References: <4640f20b$1@news.upm.es> <1178723724.958486.24820@u30g2000hsc.googlegroups.com> <464244d8$1@news.upm.es> NNTP-Posting-Host: 66.126.103.122 Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable X-Trace: posting.google.com 1178753229 27022 127.0.0.1 (9 May 2007 23:27:09 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Wed, 9 May 2007 23:27:09 +0000 (UTC) In-Reply-To: <464244d8$1@news.upm.es> User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.7.12) Gecko/20050922 Fedora/1.7.12-1.3.1,gzip(gfe),gzip(gfe) Complaints-To: groups-abuse@google.com Injection-Info: e65g2000hsc.googlegroups.com; posting-host=66.126.103.122; posting-account=cw1zeQwAAABOY2vF_g6V_9cdsyY_wV9w Xref: g2news1.google.com comp.lang.ada:15699 Date: 2007-05-09T16:27:08-07:00 List-Id: On May 9, 3:00 pm, Manuel Collado wrote: > Adam Beneschan escribi=F3: > Well, JEWL uses tasks internally. So, who knows... > > No, I believe that all objects, including static package variables > > *and* including allocated objects that have not yet been deallocated, > > are supposed to be finalized when the environment task completes. > > 10.2(25), 7.6.1(10). > > The fact is that there is a significant difference in behaviour between > variables in the main procedure and static package variables. Example: > > 1. The following code always terminates smoothly. > > --- main1.adb --------------------------------------- > with Jewl.Simple_Windows; use Jewl.Simple_Windows; > > procedure Main1 is > My_Frame: Frame_Type :=3D Frame (200, 100, "Frame 1", 'Q'); > Ok: Button_Type :=3D Button (My_Frame, (50, 20), 80, 25, "OK", 'Q'); > C: Character; > begin > C :=3D Next_Command; -- just wait for any 'frame' event > end Main1; > ---------------------------------------------------- > > 2. The following alternate code may not terminate (remains as a zombie > process). Requires explicit termination of the Frame, either by the [X] > at the top-rigth corner or by 'Close(My_Frame)'. > > --- main2.adb --------------------------------------- > procedure Main2 is > begin > Do_Frame; -- just wait for any GUI event > end Main2; > > --- pkg_frame.ads --------------------------------------- > package Pkg_Frame is > procedure Do_Frame; > end Pkg_Frame; > > --- main1.adb --------------------------------------- > with Jewl.Simple_Windows; use Jewl.Simple_Windows; > > package body Pkg_Frame is > My_Frame: Frame_Type :=3D Frame (200, 100, "Frame 2", 'Q'); > Ok: Button_Type :=3D Button (My_Frame, (50, 20), 80, 25, "OK", 'Q'); > C: Character; > > procedure Do_Frame is > begin > C :=3D Next_Command; -- just wait for any GUI event > -- POSSIBLE IMPROPER TERMINATION -- > -- may be fixed by enabling the following statement > -- Close (My_Frame); > end Do_Frame; > > end Pkg_Frame; > ---------------------------------------------------- > > Could the My_Frame declaration scope interfere with possible > unterminated tasks inside JEWL? Maybe. I don't know anything about JEWL, so I don't know what the declaration of "Frame_Type" is or what the "Frame" function does. But if the Frame function uses an allocator to create an access-to-task, and if Frame_Type is a controlled type (or has controlled components) whose Finalize routine does something that terminates that task, then I can see how you would have a problem. According to 9.3, if you (or some routine in JEWL) have started a task with an allocator, then that task depends on the master that elaborates the access-to-task *type* (and any enclosing master). Assuming the access type is declared at the library level somewhere inside JEWL, then the only master it depends on is the environment task. When you declare My_Frame inside your main procedure, then as soon as the procedure completes, My_Frame is finalized. I'm assuming that its Finalize routine (or the Finalize routine of a component) has code that causes any task created by My_Frame's initialization to terminate. So this will cause things to terminate cleanly. When you declare My_Frame at the library level, you've got a Catch-22 problem. 10.2(25) says, "When the environment task completes..., it waits for the termination of all such tasks, and then finalizes any remaining objects of the partition". Again, assuming My_Frame's finalize would terminate the task, the task termination would need to be performed by the object finalization; but 10.2(25) says that task termination must come *first*, before object finalization. Yikes! So it does look like you need to finalize My_Frame explicitly (probably by calling Close). It seems like there's a flaw somewhere. Possibly, JEWL needs a "shutdown" routine to terminate any tasks that are still running. Offhand, though, I don't see any good way to rearrange your program to make sure library-level objects are finalized *before* the tasks are terminated, except by making sure all your Frame_Type objects and such are declared inside some procedure, which probably means making a lot of your packages subunits of some big procedure, which is probably obnoxious. I don't think Ada has a way to tell the environment task that some objects, or objects of some specified types, should be finalized *before* waiting for task termination. It would be helpful here, but there may not be a good way to add a language feature to facilitate this. -- Adam