* Finalization of static package variables @ 2007-05-08 21:55 Manuel Collado 2007-05-09 8:13 ` Alex R. Mosteo 2007-05-09 8:20 ` Stephen Leake 0 siblings, 2 replies; 25+ messages in thread From: Manuel Collado @ 2007-05-08 21:55 UTC (permalink / raw) Variables declared in the global scope of a package body seem not to be finalized automatically at the end of the whole program (using GNAT 3.15p on WindowsXP). If some of these variables contain certain GUI stuff, the program remains as a zombie process after the main procedure termination. After several trial-and-error attemps, an Unchecked_Deallocation on these variables seems to do the trick (the whole program terminates smoothly). But this is probably not standard-conformant (ARM 13.11.2-16). If there a standard way of forcing finalization of static package variables at program termination? I.e., without declaring them as dynamic, or inside a main procedure, or calling explicitly the finalization actions. Thanks in advance. -- Manuel Collado - http://lml.ls.fi.upm.es/~mcollado ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-08 21:55 Finalization of static package variables Manuel Collado @ 2007-05-09 8:13 ` Alex R. Mosteo 2007-05-09 8:20 ` Stephen Leake 1 sibling, 0 replies; 25+ messages in thread From: Alex R. Mosteo @ 2007-05-09 8:13 UTC (permalink / raw) Manuel Collado wrote: > Variables declared in the global scope of a package body seem not to be > finalized automatically at the end of the whole program (using GNAT > 3.15p on WindowsXP). > > If some of these variables contain certain GUI stuff, the program > remains as a zombie process after the main procedure termination. > > After several trial-and-error attemps, an Unchecked_Deallocation on > these variables seems to do the trick (the whole program terminates > smoothly). But this is probably not standard-conformant (ARM 13.11.2-16). > > If there a standard way of forcing finalization of static package > variables at program termination? I.e., without declaring them as > dynamic, or inside a main procedure, or calling explicitly the > finalization actions. You say using Unchecked_Deallocation does work, so that makes me think that your global variables aren't Controlled objects but accesses to controlled objects. Am I right? Deallocating a Controlled object indeed should trigger a Finalize call on it. Otherwise, I would expect that Finalize is called on any Controlled object at program finalization, even if it's a variable at the library level in a package body... ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-08 21:55 Finalization of static package variables Manuel Collado 2007-05-09 8:13 ` Alex R. Mosteo @ 2007-05-09 8:20 ` Stephen Leake 2007-05-09 15:15 ` Adam Beneschan 2007-05-09 22:19 ` Manuel Collado 1 sibling, 2 replies; 25+ messages in thread From: Stephen Leake @ 2007-05-09 8:20 UTC (permalink / raw) Manuel Collado <m.collado@lml.ls.fi.upm.es> writes: > Variables declared in the global scope of a package body seem not to > be finalized automatically at the end of the whole program (using GNAT > 3.15p on WindowsXP). Is there some reason you are not using a more current version of GNAT? > If some of these variables contain certain GUI stuff, the program > remains as a zombie process after the main procedure termination. Technically, that cannot be true; the "main procedure" is the "environment task", and it does not "terminate" (in the Ada definition of that word) until all of the tasks it has spawned have "terminated". I think that what you are saying is that there are some tasks that have not terminated when the main procedure is ready to terminate, and that in fact those tasks never terminate. > After several trial-and-error attemps, an Unchecked_Deallocation on > these variables seems to do the trick (the whole program terminates > smoothly). Unchecked_Deallocation is used on access variables (aka "pointers"). Such variables are _not_ automatically finalized by Ada; calling Unchecked_Deallocation is the standard-compliant way to finalize them. > But this is probably not standard-conformant (ARM 13.11.2-16). This paragraph says: Evaluating a name that denotes a nonexistent object is erroneous. The execution of a call to an instance of Unchecked_Deallocation is erroneous if the object was created other than by an allocator for an access type whose pool is Name'Storage_Pool. I don't see how that is relevant to your problem. What version of the ARM are you quoting? When you say "ARM" without a year, it implies "current" which means "Ada 2007" (or, informally, "Ada 2005"). > If there a standard way of forcing finalization of static package > variables at program termination? I.e., without declaring them as > dynamic, or inside a main procedure, or calling explicitly the > finalization actions. If the type of the variable is derived from Ada.Finalization.Controlled or Limited_Controlled, it will be finalized when it goes out of scope. Otherwise, it won't be. However, a static package variable never goes out of scope, so that is no help. Calling Unchecked_Deallocation does seem to be the correct approach to what you need to do. Why is it a problem? Posting code that outlines what you are doing would help a lot. -- -- Stephe ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-09 8:20 ` Stephen Leake @ 2007-05-09 15:15 ` Adam Beneschan 2007-05-09 16:01 ` Markus E Leypold 2007-05-09 22:00 ` Manuel Collado 2007-05-09 22:19 ` Manuel Collado 1 sibling, 2 replies; 25+ messages in thread From: Adam Beneschan @ 2007-05-09 15:15 UTC (permalink / raw) On May 9, 1:20 am, Stephen Leake <stephen_le...@stephe-leake.org> wrote: > Manuel Collado <m.coll...@lml.ls.fi.upm.es> writes: > > Variables declared in the global scope of a package body seem not to > > be finalized automatically at the end of the whole program (using GNAT > > 3.15p on WindowsXP). > > Is there some reason you are not using a more current version of GNAT? > > > If some of these variables contain certain GUI stuff, the program > > remains as a zombie process after the main procedure termination. > > Technically, that cannot be true; the "main procedure" is the > "environment task", and it does not "terminate" (in the Ada definition > of that word) until all of the tasks it has spawned have "terminated". > > I think that what you are saying is that there are some tasks that > have not terminated when the main procedure is ready to terminate, and > that in fact those tasks never terminate. Except that Manuel never said he was using tasks. I'm envisioning that he probably has a controlled object whose initialization causes some Windows process to be spawned (either directly or via some function in some other GUI library), and finalization causes the process to be terminated. > If the type of the variable is derived from > Ada.Finalization.Controlled or Limited_Controlled, it will be > finalized when it goes out of scope. Otherwise, it won't be. > > However, a static package variable never goes out of scope, so that is > no help. 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). -- Adam ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-09 15:15 ` Adam Beneschan @ 2007-05-09 16:01 ` Markus E Leypold 2007-05-09 22:00 ` Manuel Collado 1 sibling, 0 replies; 25+ messages in thread From: Markus E Leypold @ 2007-05-09 16:01 UTC (permalink / raw) Adam Beneschan <adam@irvine.com> writes: > On May 9, 1:20 am, Stephen Leake <stephen_le...@stephe-leake.org> > wrote: >> Manuel Collado <m.coll...@lml.ls.fi.upm.es> writes: >> > Variables declared in the global scope of a package body seem not to >> > be finalized automatically at the end of the whole program (using GNAT >> > 3.15p on WindowsXP). >> >> Is there some reason you are not using a more current version of GNAT? >> >> > If some of these variables contain certain GUI stuff, the program >> > remains as a zombie process after the main procedure termination. >> >> Technically, that cannot be true; the "main procedure" is the >> "environment task", and it does not "terminate" (in the Ada definition >> of that word) until all of the tasks it has spawned have "terminated". >> >> I think that what you are saying is that there are some tasks that >> have not terminated when the main procedure is ready to terminate, and >> that in fact those tasks never terminate. > > Except that Manuel never said he was using tasks. I'm envisioning > that he probably has a controlled object whose initialization causes > some Windows process to be spawned (either directly or via some > function in some other GUI library), and finalization causes the > process to be terminated. > > >> If the type of the variable is derived from >> Ada.Finalization.Controlled or Limited_Controlled, it will be >> finalized when it goes out of scope. Otherwise, it won't be. >> >> However, a static package variable never goes out of scope, so that is >> no help. > > 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). Absolutely right. With Gnat, though, that isn't the case if the process is terminated by an external signal, e.g. SIGINT from keyboard or the ^C handler in the windows console. I wonder wether it is that which is puzzling the OP. Regards -- Markus ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-09 15:15 ` Adam Beneschan 2007-05-09 16:01 ` Markus E Leypold @ 2007-05-09 22:00 ` Manuel Collado 2007-05-09 23:27 ` Adam Beneschan 2007-05-10 10:57 ` Stephen Leake 1 sibling, 2 replies; 25+ messages in thread From: Manuel Collado @ 2007-05-09 22:00 UTC (permalink / raw) Adam Beneschan escribi�: > On May 9, 1:20 am, Stephen Leake <stephen_le...@stephe-leake.org> > wrote: >> Manuel Collado <m.coll...@lml.ls.fi.upm.es> writes: >>> Variables declared in the global scope of a package body seem not to >>> be finalized automatically at the end of the whole program (using GNAT >>> 3.15p on WindowsXP). >> Is there some reason you are not using a more current version of GNAT? Using JEWL-1.6, last updated for GNAT-3.15p. Unable to use it with GPS200x (until now - probably some required libraries not properly installed). >> >>> If some of these variables contain certain GUI stuff, the program >>> remains as a zombie process after the main procedure termination. >> Technically, that cannot be true; the "main procedure" is the >> "environment task", and it does not "terminate" (in the Ada definition >> of that word) until all of the tasks it has spawned have "terminated". >> >> I think that what you are saying is that there are some tasks that >> have not terminated when the main procedure is ready to terminate, and >> that in fact those tasks never terminate. > > Except that Manuel never said he was using tasks. I'm envisioning > that he probably has a controlled object whose initialization causes > some Windows process to be spawned (either directly or via some > function in some other GUI library), and finalization causes the > process to be terminated. Well, JEWL uses tasks internally. So, who knows... > >> If the type of the variable is derived from >> Ada.Finalization.Controlled or Limited_Controlled, it will be >> finalized when it goes out of scope. Otherwise, it won't be. >> >> However, a static package variable never goes out of scope, so that is >> no help. > > 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 := Frame (200, 100, "Frame 1", 'Q'); Ok: Button_Type := Button (My_Frame, (50, 20), 80, 25, "OK", 'Q'); C: Character; begin C := 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 := Frame (200, 100, "Frame 2", 'Q'); Ok: Button_Type := Button (My_Frame, (50, 20), 80, 25, "OK", 'Q'); C: Character; procedure Do_Frame is begin C := 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? Regards. -- Manuel Collado - http://lml.ls.fi.upm.es/~mcollado ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-09 22:00 ` Manuel Collado @ 2007-05-09 23:27 ` Adam Beneschan 2007-05-10 4:52 ` Jeffrey R. Carter ` (2 more replies) 2007-05-10 10:57 ` Stephen Leake 1 sibling, 3 replies; 25+ messages in thread From: Adam Beneschan @ 2007-05-09 23:27 UTC (permalink / raw) On May 9, 3:00 pm, Manuel Collado <m.coll...@lml.ls.fi.upm.es> wrote: > Adam Beneschan escribió: > 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 := Frame (200, 100, "Frame 1", 'Q'); > Ok: Button_Type := Button (My_Frame, (50, 20), 80, 25, "OK", 'Q'); > C: Character; > begin > C := 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 := Frame (200, 100, "Frame 2", 'Q'); > Ok: Button_Type := Button (My_Frame, (50, 20), 80, 25, "OK", 'Q'); > C: Character; > > procedure Do_Frame is > begin > C := 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 ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-09 23:27 ` Adam Beneschan @ 2007-05-10 4:52 ` Jeffrey R. Carter 2007-05-16 0:41 ` Randy Brukardt 2007-05-10 8:16 ` Alex R. Mosteo 2007-05-16 0:36 ` Randy Brukardt 2 siblings, 1 reply; 25+ messages in thread From: Jeffrey R. Carter @ 2007-05-10 4:52 UTC (permalink / raw) Adam Beneschan wrote: > > 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. The task in JEWL is a singleton task declared in the specification of a library-level private package. This task keeps track of how many frames have been created and doesn't end until they've all been destroyed. The frame in the subprogram is destroyed when it is finalized when the subprogram returns; the frame in the package won't be finalized until the task ends. With the frame in a subprogram, the call to Close isn't strictly necessary (though it's a good idea). With the frame in the package, the call to Close is necessary. Otherwise, the task won't end until the frame is finalized, and the frame won't be finalized until the task ends. -- Jeff Carter "C++ is like giving an AK-47 to a monk, shooting him full of crack and letting him loose in a mall and expecting him to balance your checking account 'when he has the time.'" Drew Olbrich 52 ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-10 4:52 ` Jeffrey R. Carter @ 2007-05-16 0:41 ` Randy Brukardt 0 siblings, 0 replies; 25+ messages in thread From: Randy Brukardt @ 2007-05-16 0:41 UTC (permalink / raw) "Jeffrey R. Carter" <spam.jrcarter.not@acm.nospam.org> wrote in message news:cyx0i.45276$n_.17025@attbi_s21... ... > The task in JEWL is a singleton task declared in the specification of a > library-level private package. This task keeps track of how many frames > have been created and doesn't end until they've all been destroyed. The > frame in the subprogram is destroyed when it is finalized when the > subprogram returns; the frame in the package won't be finalized until > the task ends. With the frame in a subprogram, the call to Close isn't > strictly necessary (though it's a good idea). With the frame in the > package, the call to Close is necessary. Otherwise, the task won't end > until the frame is finalized, and the frame won't be finalized until the > task ends. Unfortunately, that isn't possible if the owner of the window (frame) is aborted or is terminated by an unexpected exception. (You can have a handler in the latter case, but that's easy to forget.) We tried that approach first with Claw, but the number of support calls about programs that wouldn't terminate (and a lot of time wasted on our end before we realized that we just had another instance of the same old user error) quickly proved the silliness of that strategy. Even if JEWL isn't technically broken in this case, it is unnecessarily fragile. BTW, the OP should know that Gnat 3.15p does this sort of finalization correctly; some earlier versions didn't, but a lot of Claw bug reports cleaned that up... Randy. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-09 23:27 ` Adam Beneschan 2007-05-10 4:52 ` Jeffrey R. Carter @ 2007-05-10 8:16 ` Alex R. Mosteo 2007-05-16 0:36 ` Randy Brukardt 2 siblings, 0 replies; 25+ messages in thread From: Alex R. Mosteo @ 2007-05-10 8:16 UTC (permalink / raw) Adam Beneschan wrote: > 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! Ahhhh... good catch! ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-09 23:27 ` Adam Beneschan 2007-05-10 4:52 ` Jeffrey R. Carter 2007-05-10 8:16 ` Alex R. Mosteo @ 2007-05-16 0:36 ` Randy Brukardt 2007-05-16 14:06 ` Adam Beneschan 2 siblings, 1 reply; 25+ messages in thread From: Randy Brukardt @ 2007-05-16 0:36 UTC (permalink / raw) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 1488 bytes --] "Adam Beneschan" <adam@irvine.com> wrote in message news:1178753228.648765.89390@e65g2000hsc.googlegroups.com... On May 9, 3:00 pm, Manuel Collado <m.coll...@lml.ls.fi.upm.es> wrote: > Adam Beneschan escribi�: > 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: This sounds awfully familiar to me; it's a problem that we had in Claw. The problem you're having appears to be that the library you arer using (JEWL) does not properly support library-level objects. We had a lot of trouble with this in Claw, in the end we found a trick to determine when the environment task is completing; then we have the main task forcibly close/finalize all open windows. Otherwise, the program would go catatonic, because the tasks would be waiting for the windows to close, but Ada says that the tasks have to end first. Moral: using an ancient library and an ancient compiler means that you'll refind all of the bugs long ago worked out. Use a newer compiler, use a library like Claw oe GWindows or even GtkAda, and you won't have these sorts of issues... Randy. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-16 0:36 ` Randy Brukardt @ 2007-05-16 14:06 ` Adam Beneschan 2007-05-16 16:47 ` Jeffrey R. Carter 2007-05-16 19:10 ` Randy Brukardt 0 siblings, 2 replies; 25+ messages in thread From: Adam Beneschan @ 2007-05-16 14:06 UTC (permalink / raw) On May 15, 5:36 pm, "Randy Brukardt" <r...@rrsoftware.com> wrote: > "Adam Beneschan" <a...@irvine.com> wrote in message > > news:1178753228.648765.89390@e65g2000hsc.googlegroups.com... > On May 9, 3:00 pm, Manuel Collado <m.coll...@lml.ls.fi.upm.es> wrote: > > > Adam Beneschan escribió: > > 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: > > This sounds awfully familiar to me; it's a problem that we had in Claw. The > problem you're having appears to be that the library you arer using (JEWL) > does not properly support library-level objects. We had a lot of trouble > with this in Claw, in the end we found a trick to determine when the > environment task is completing; then we have the main task forcibly > close/finalize all open windows. So, to go back to a point I briefly mentioned in my previous post: does Ada need a feature that would allow you to call your own finalization procedure or something when the environment task is completing, so that you don't have to do this using trickery? Maybe something like: package Ada.Finalization.Environment is type Finalization_Proc is access procedure; procedure At_Environment_Task_Completion (Proc : in Finalization_Proc); end Ada.Finalization.Environment; Then, the body of the "Environment_Task" implicit task would call the main subprogram and then call any procedures registered with At_Environment_Task_Completion, in arbitrary order; you could possibly add an exception handler to the Environment_Task body to call the finalization procedures too. That would be a simple way to solve this sort of problem without adding any language syntax. -- Adam ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-16 14:06 ` Adam Beneschan @ 2007-05-16 16:47 ` Jeffrey R. Carter 2007-05-16 19:10 ` Randy Brukardt 1 sibling, 0 replies; 25+ messages in thread From: Jeffrey R. Carter @ 2007-05-16 16:47 UTC (permalink / raw) Adam Beneschan wrote: > > So, to go back to a point I briefly mentioned in my previous post: > does Ada need a feature that would allow you to call your own > finalization procedure or something when the environment task is > completing, so that you don't have to do this using trickery? Maybe > something like: > > package Ada.Finalization.Environment is > type Finalization_Proc is access procedure; > procedure At_Environment_Task_Completion (Proc : in > Finalization_Proc); > end Ada.Finalization.Environment; > > Then, the body of the "Environment_Task" implicit task would call the > main subprogram and then call any procedures registered with > At_Environment_Task_Completion, in arbitrary order; you could possibly > add an exception handler to the Environment_Task body to call the > finalization procedures too. > > That would be a simple way to solve this sort of problem without > adding any language syntax. Not for this problem. This was simply a misunderstanding of how to use JEWL; JEWL windows should always be explicitly closed. In the general case, I'd think this indicates a design problem, not a failure of the language. -- Jeff Carter "I like it when the support group complains that they have insufficient data on mean time to repair bugs in Ada software." Robert I. Eachus 91 ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-16 14:06 ` Adam Beneschan 2007-05-16 16:47 ` Jeffrey R. Carter @ 2007-05-16 19:10 ` Randy Brukardt 2007-05-22 4:41 ` christoph.grein 1 sibling, 1 reply; 25+ messages in thread From: Randy Brukardt @ 2007-05-16 19:10 UTC (permalink / raw) "Adam Beneschan" <adam@irvine.com> wrote in message news:1179324410.556097.234870@u30g2000hsc.googlegroups.com... ... > So, to go back to a point I briefly mentioned in my previous post: > does Ada need a feature that would allow you to call your own > finalization procedure or something when the environment task is > completing, so that you don't have to do this using trickery? No, because your proposed "fix" is more complex than the trick, which is simply to use Ada.Task_Identification: -- In a library package: with Ada.Task_Identification; use Ada.Task_Identification; Env_Task_Id : constant Task_Id := Current_Task; Now, in any task that you want to take special action if the main subprogram has exited: if Is_Completed (Env_Task_Id) then Originally, when I dreamt this up for Claw, no compilers actually implemented it. Indeed, I asked the question to the ARG, which became AI-206. When that was resolved, ACATS test CXC7004 was added to test it, so it is likely that all current compilers support doing this. (Surely all of the Windows ones do, we sent bug reports to all of them...) So there is no need for something fancier, the capability already exists. Randy. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-16 19:10 ` Randy Brukardt @ 2007-05-22 4:41 ` christoph.grein 2007-05-22 6:25 ` tmoran 0 siblings, 1 reply; 25+ messages in thread From: christoph.grein @ 2007-05-22 4:41 UTC (permalink / raw) On 16 Mai, 21:10, "Randy Brukardt" <r...@rrsoftware.com> wrote: > No, because your proposed "fix" is more complex than the trick, which is > simply to use Ada.Task_Identification: > > -- In a librarypackage: > with Ada.Task_Identification; use Ada.Task_Identification; > > Env_Task_Id : constant Task_Id := Current_Task; > > Now, in any task that you want to take special action if the main subprogram > has exited: > > if Is_Completed (Env_Task_Id) then There is no such function as is_Completed. Which do you mean: is_Terminated or not is_Callable? ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-22 4:41 ` christoph.grein @ 2007-05-22 6:25 ` tmoran 2007-05-22 22:19 ` Randy Brukardt 0 siblings, 1 reply; 25+ messages in thread From: tmoran @ 2007-05-22 6:25 UTC (permalink / raw) > > if Is_Completed (Env_Task_Id) then > > There is no such function as is_Completed. Which do you mean: > is_Terminated > or > not is_Callable? Is_Callable. Download the free Claw from www.rrsoftware.com and look in claw.adb to see. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-22 6:25 ` tmoran @ 2007-05-22 22:19 ` Randy Brukardt 0 siblings, 0 replies; 25+ messages in thread From: Randy Brukardt @ 2007-05-22 22:19 UTC (permalink / raw) <tmoran@acm.org> wrote in message news:7u6dnXGpNfteEc_bnZ2dnUVZ_uejnZ2d@comcast.com... > > > if Is_Completed (Env_Task_Id) then > > > > There is no such function as is_Completed. Which do you mean: > > is_Terminated > > or > > not is_Callable? > Is_Callable. Download the free Claw from www.rrsoftware.com and > look in claw.adb to see. Right. Shoulda checked more carefully... Randy. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-09 22:00 ` Manuel Collado 2007-05-09 23:27 ` Adam Beneschan @ 2007-05-10 10:57 ` Stephen Leake 1 sibling, 0 replies; 25+ messages in thread From: Stephen Leake @ 2007-05-10 10:57 UTC (permalink / raw) Manuel Collado <m.collado@lml.ls.fi.upm.es> writes: > 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)'. That would seem to be normal, expected behavior for a GUI program; it runs until the user ends it. Why is this a problem? -- -- Stephe ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-09 8:20 ` Stephen Leake 2007-05-09 15:15 ` Adam Beneschan @ 2007-05-09 22:19 ` Manuel Collado 2007-05-10 5:38 ` AW: " Grein, Christoph (Fa. ESG) 2007-05-10 10:55 ` Stephen Leake 1 sibling, 2 replies; 25+ messages in thread From: Manuel Collado @ 2007-05-09 22:19 UTC (permalink / raw) Stephen Leake escribi�: > Manuel Collado <m.collado@lml.ls.fi.upm.es> writes: > >> Variables declared in the global scope of a package body seem not to >> be finalized automatically at the end of the whole program (using GNAT >> 3.15p on WindowsXP). > [...] >> After several trial-and-error attemps, an Unchecked_Deallocation on >> these variables seems to do the trick (the whole program terminates >> smoothly). > > Unchecked_Deallocation is used on access variables (aka "pointers"). > Such variables are _not_ automatically finalized by Ada; calling > Unchecked_Deallocation is the standard-compliant way to finalize them. > >> But this is probably not standard-conformant (ARM 13.11.2-16). > > This paragraph says: > > Evaluating a name that denotes a nonexistent object is erroneous. > The execution of a call to an instance of Unchecked_Deallocation > is erroneous if the object was created other than by an allocator > for an access type whose pool is Name'Storage_Pool. > > I don't see how that is relevant to your problem. "... erroneous ... if the object was created other than by an allocator for an access type whose pool is Name'Storage_Pool." Are static package variables allocated in this pool? > > What version of the ARM are you quoting? When you say "ARM" without a > year, it implies "current" which means "Ada 2007" (or, informally, > "Ada 2005"). Doesn't "using GNAT 3.15p" give you any hint :-) ? > [...] > Posting code that outlines what you are doing would help a lot. ------------------------------------ package body Pkg_Dialog is My_Dialog: aliased Dialog_Type := Dialog (200, 100, "Dialog 3", 'Q'); ... procedure Do_Dialog is begin ... exercise My_Dialog ... declare type Dialog_Access is access all Dialog_Type; procedure Dispose is new Ada.Unchecked_Deallocation ( Object => Dialog_Type, Name => Dialog_Access ); Pointer: Dialog_Access := My_Dialog'access; begin Dispose (Pointer); -- force My_Dialog finalization end; end Do_Dialog; end Pkg_Dialog; ----------------------------------- Regards. -- Manuel Collado - http://lml.ls.fi.upm.es/~mcollado ^ permalink raw reply [flat|nested] 25+ messages in thread
* AW: Finalization of static package variables 2007-05-09 22:19 ` Manuel Collado @ 2007-05-10 5:38 ` Grein, Christoph (Fa. ESG) 2007-05-10 10:55 ` Stephen Leake 1 sibling, 0 replies; 25+ messages in thread From: Grein, Christoph (Fa. ESG) @ 2007-05-10 5:38 UTC (permalink / raw) To: comp.lang.ada When the main task terminates, all variables and constants go out of scope, so also static variables and constants (those declared immediately within library units, whether allocated by declaration or via an allocator) are finalized. If this is not the case with your compiler, it has a bug. The latest Gnat 6.0.1 does finalize everything. Eurocopter Deutschland GmbH Sitz der Gesellschaft/Registered Office: Donauwoerth Registergericht/Registration Court: Amtsgericht Augsburg HRB 16508 Vorsitzender des Aufsichtsrates/Chairman of the Supervisory Board: Dr. Lutz Bertling Geschaeftsfuehrung/Board of Management: Dr. Wolfgang Schoder, Vorsitzender/CEO; Friedrich-Wilhelm Hormel; Ralf Barnscheidt CONFIDENTIALITY NOTICE This communication and the information it contains is intended for the addressee(s) named above and for no other persons or organizations. It is confidential and may be legally privileged and protected by law. The unauthorized use, copying or disclosure of this communication or any part of it is prohibited and may be unlawful. If you have received this communication in error, kindly notify us by return e-mail and discard and/or delete the communication. Thank you very much. It is possible for e-mails to be intercepted or affected by viruses. Whilst we maintain virus checks on our e-mails, we accept no liability for viruses or other material which might be introduced with this message. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-09 22:19 ` Manuel Collado 2007-05-10 5:38 ` AW: " Grein, Christoph (Fa. ESG) @ 2007-05-10 10:55 ` Stephen Leake 2007-05-11 18:12 ` Manuel Collado 1 sibling, 1 reply; 25+ messages in thread From: Stephen Leake @ 2007-05-10 10:55 UTC (permalink / raw) Manuel Collado <m.collado@lml.ls.fi.upm.es> writes: > Stephen Leake escribi�: >> Manuel Collado <m.collado@lml.ls.fi.upm.es> writes: >> >>> Variables declared in the global scope of a package body seem not to >>> be finalized automatically at the end of the whole program (using GNAT >>> 3.15p on WindowsXP). >> [...] >>> After several trial-and-error attemps, an Unchecked_Deallocation on >>> these variables seems to do the trick (the whole program terminates >>> smoothly). >> Unchecked_Deallocation is used on access variables (aka "pointers"). >> Such variables are _not_ automatically finalized by Ada; calling >> Unchecked_Deallocation is the standard-compliant way to finalize them. >> >>> But this is probably not standard-conformant (ARM 13.11.2-16). >> This paragraph says: >> Evaluating a name that denotes a nonexistent object is erroneous. >> The execution of a call to an instance of Unchecked_Deallocation >> is erroneous if the object was created other than by an allocator >> for an access type whose pool is Name'Storage_Pool. >> I don't see how that is relevant to your problem. > > "... erroneous ... if the object was created other than by an > allocator for an access type whose pool is Name'Storage_Pool." > > Are static package variables allocated in this pool? static package variables are created in the heap. If they are _pointers_, the objects that they point to are allocated in some pool. There is a big difference between a pointer variable, and the object it points to. >> What version of the ARM are you quoting? When you say "ARM" without a >> year, it implies "current" which means "Ada 2007" (or, informally, >> "Ada 2005"). > > Doesn't "using GNAT 3.15p" give you any hint :-) ? Ah, sorry, forgot that part. -- -- Stephe ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-10 10:55 ` Stephen Leake @ 2007-05-11 18:12 ` Manuel Collado 2007-05-11 18:26 ` Robert A Duff 0 siblings, 1 reply; 25+ messages in thread From: Manuel Collado @ 2007-05-11 18:12 UTC (permalink / raw) Stephen Leake escribi�: > Manuel Collado <m.collado@lml.ls.fi.upm.es> writes: >> Stephen Leake escribi�: >>> Manuel Collado <m.collado@lml.ls.fi.upm.es> writes: >>> ... >>>> But this is probably not standard-conformant (ARM 13.11.2-16). >>> This paragraph says: >>> Evaluating a name that denotes a nonexistent object is erroneous. >>> The execution of a call to an instance of Unchecked_Deallocation >>> is erroneous if the object was created other than by an allocator >>> for an access type whose pool is Name'Storage_Pool. >>> I don't see how that is relevant to your problem. >> "... erroneous ... if the object was created other than by an >> allocator for an access type whose pool is Name'Storage_Pool." >> >> Are static package variables allocated in this pool? > > static package variables are created in the heap. > > If they are _pointers_, the objects that they point to are allocated in > some pool. > > There is a big difference between a pointer variable, and the object > it points to. That's what I've teached to my students for decades :-) But an access variable can refer to a static variable. Is the following Ada95 code schema legal? What about Ada200x (or just Ada, if you want)? It seems to work in GNAT-3.15p (it lets finalize 'Edit'), but ... ------------------------------------------------- package body View_Editor is Edit: aliased Dialog_Type := Dialog (420, 350, "Conversion Rates", 'Q', Main_Font); [...snipped...] procedure Editor_Destroy is type Dialog_Access is access all Dialog_Type; procedure Dispose is new Ada.Unchecked_Deallocation ( Object => Dialog_Type, Name => Dialog_Access ); Pointer: Dialog_Access := Edit'access; begin Dispose (Pointer); end Editor_Destroy; end View_Editor; -------------------------------------------------- Thanks. -- Manuel Collado - http://lml.ls.fi.upm.es/~mcollado ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables 2007-05-11 18:12 ` Manuel Collado @ 2007-05-11 18:26 ` Robert A Duff 2007-05-12 19:17 ` Finalization of static package variables - summary Manuel Collado 0 siblings, 1 reply; 25+ messages in thread From: Robert A Duff @ 2007-05-11 18:26 UTC (permalink / raw) Manuel Collado <m.collado@lml.ls.fi.upm.es> writes: > But an access variable can refer to a static variable. Is the following > Ada95 code schema legal? It is erroneous, which is the Ada term for "wrong, and will cause totally unpredictable behavior at run time." Most likely, you will corrupt the heap data structures if you try to free objects that are not heap allocated. Note that if you erase the "Dispose", then Edit will be finalized when program is done. >...What about Ada200x (or just Ada, if you want)? Same answer. > It seems to work in GNAT-3.15p (it lets finalize 'Edit'), but ... > > ------------------------------------------------- > package body View_Editor is > > Edit: aliased Dialog_Type := > Dialog (420, 350, "Conversion Rates", 'Q', Main_Font); > > [...snipped...] > > procedure Editor_Destroy is > type Dialog_Access is access all Dialog_Type; > procedure Dispose is > new Ada.Unchecked_Deallocation ( > Object => Dialog_Type, > Name => Dialog_Access ); > Pointer: Dialog_Access := Edit'access; > begin > Dispose (Pointer); > end Editor_Destroy; > > end View_Editor; - Bob ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables - summary 2007-05-11 18:26 ` Robert A Duff @ 2007-05-12 19:17 ` Manuel Collado 2007-05-16 0:49 ` Randy Brukardt 0 siblings, 1 reply; 25+ messages in thread From: Manuel Collado @ 2007-05-12 19:17 UTC (permalink / raw) Thanks to all who responded. Now it is clear that: 1.- Static packages variables are properly finalized at the end of the main task. 2.- There is a problem with JEWL, if modal dialogs are declared as static package variables. 2.1.- JEWL doesn't provide an explicit 'close' action for this kind of top level windows. It just provides one for 'frames'. 2.2.- After the main procedure ends, there is a deadlock between the main (environment) task and the internal JEWL message task (that is waiting for finalization of all top level windows). 2.3.- Being static variables, the mentioned modal dialogs cannot be 'unchecked_deallocated' to force its finalization To gain the possibility of declaring modal dialogs as static package variables, I've patched the JEWL sources to add a 'close()' procedure for modal dialogs. Thanks again. -- Manuel Collado - http://lml.ls.fi.upm.es/~mcollado ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: Finalization of static package variables - summary 2007-05-12 19:17 ` Finalization of static package variables - summary Manuel Collado @ 2007-05-16 0:49 ` Randy Brukardt 0 siblings, 0 replies; 25+ messages in thread From: Randy Brukardt @ 2007-05-16 0:49 UTC (permalink / raw) "Manuel Collado" <m.collado@lml.ls.fi.upm.es> wrote in message news:46461336@news.upm.es... ... > To gain the possibility of declaring modal dialogs as static package > variables, I've patched the JEWL sources to add a 'close()' procedure > for modal dialogs. As I mentioned previously, this really doesn't work: if your program has a bug and raises an unhandled exception, it will deadlock again (and probably not even tell you what happened!). You could try to put handlers all over the place, but that is an amazing pain and quite fragile. I think you either have to use JEWL as it was intended (with modal dialogs declared in subprograms; I can't think of any good reason to declare a modal dialog in a package anyway: it can't live very long, since it prevents everything else from working) or switch to a different GUI library. (I'm partial to Claw, but any of them would work.) Randy. ^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2007-05-22 22:19 UTC | newest] Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2007-05-08 21:55 Finalization of static package variables Manuel Collado 2007-05-09 8:13 ` Alex R. Mosteo 2007-05-09 8:20 ` Stephen Leake 2007-05-09 15:15 ` Adam Beneschan 2007-05-09 16:01 ` Markus E Leypold 2007-05-09 22:00 ` Manuel Collado 2007-05-09 23:27 ` Adam Beneschan 2007-05-10 4:52 ` Jeffrey R. Carter 2007-05-16 0:41 ` Randy Brukardt 2007-05-10 8:16 ` Alex R. Mosteo 2007-05-16 0:36 ` Randy Brukardt 2007-05-16 14:06 ` Adam Beneschan 2007-05-16 16:47 ` Jeffrey R. Carter 2007-05-16 19:10 ` Randy Brukardt 2007-05-22 4:41 ` christoph.grein 2007-05-22 6:25 ` tmoran 2007-05-22 22:19 ` Randy Brukardt 2007-05-10 10:57 ` Stephen Leake 2007-05-09 22:19 ` Manuel Collado 2007-05-10 5:38 ` AW: " Grein, Christoph (Fa. ESG) 2007-05-10 10:55 ` Stephen Leake 2007-05-11 18:12 ` Manuel Collado 2007-05-11 18:26 ` Robert A Duff 2007-05-12 19:17 ` Finalization of static package variables - summary Manuel Collado 2007-05-16 0:49 ` Randy Brukardt
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox