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=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!feeder.eternal-september.org!aioe.org!.POSTED!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: Finalization of library level tasks Date: Sun, 15 Apr 2018 17:15:17 +0200 Organization: Aioe.org NNTP Server Message-ID: References: NNTP-Posting-Host: kQkuQcRDy1QFvWpyB1foYw.user.gioia.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.7.0 X-Notice: Filtered by postfilter v. 0.8.3 Content-Language: en-US Xref: reader02.eternal-september.org comp.lang.ada:51519 Date: 2018-04-15T17:15:17+02:00 List-Id: On 2018-04-15 16:54, Jeffrey R. Carter wrote: > On 04/15/2018 04:12 PM, Dmitry A. Kazakov wrote: >> >> The problem is that Finalize is called when the object is declared in >> a nested scope: >> >>    procedure Main is >>       Data : X; >>    begin >>       Data.Worker := new Worker_Type; >>    end Main; -- Finalize is called (and terminates the task) >> >> This does not work: >> >>    package Library_Level is >>       Data : X; >>    end Library_Level; >> >>    with Library_Level; >>    procedure Main is >>    begin >>       Library_Level.Data.Worker := new Worker_Type; >>    end Main; -- Finalize is not called (presumably waiting for the task) > > A task declared by an allocator (usually) depends on the thing that the > access type is declared in; here, that's a library-level pkg. > > An object declaration such as Data goes out of scope when the thing that > it's declared in goes away. In a procedure, the procedure can end and > Data can be finalized, even though Data.Worker.all is still running. You > might, for example, copy Data.Worker to another variable of the access > type that will exist after the procedure call ends. Or you may want the > task to exist and run with no way to refer to it; tasks in worker pools > often work this way. That would not work because the task actually has an access discriminant pointing the container type. > When Data is declared in a library-level pkg, it's finalized when the > pkg goes out of scope, which doesn't happen until all library-level > tasks have terminated. Since Data.Worker has a library-level access > type, Data.Worker.all is a library-level task. Yes. The problem is the order of finalization. For some unclear reason the task's access type is attempted before the object that contains that access type because they are in the same scope. The effect is that task termination is requested prematurely. I hoped that there is some trick, e.g. fooling the accessibility rules of the access type, some sort of Unchecked_Allocation. Ada 83 had pragma Controlled to require the compiler to keep its hands off, alas, it was removed. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de