comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Tail recursion upon task destruction
Date: Wed, 18 Nov 2009 09:41:01 +0100
Date: 2009-11-18T09:41:00+01:00	[thread overview]
Message-ID: <1c0f7smxa240s.86mhal9qudx.dlg@40tude.net> (raw)
In-Reply-To: hdv559$e27$1@munin.nbi.dk

On Tue, 17 Nov 2009 15:38:45 -0600, Randy Brukardt wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
> news:jv8fpjlb56be$.1afg8uuwigjop$.dlg@40tude.net...
>> Consider a task encapsulated in an object in either way:
>>
>>   type Device is
>>      Driver : Driver_Task (Device'Access);
>>
>> or
>>
>>   type Device is
>>      Driver : not null access Driver_Task := Driver_Task (Device'Access);
>>
>> Let the object is allocated dynamically and we wanted to destroy it from
>> the task.
> 
> Ada does not allow an object to destroy/free itself. That's generally a good 
> thing, because such an object cannot be an ADT

Only if we considered finalization request an operation. There are merits
in your point though.

> (it cannot be used as the 
> element of a container, for instance), and such a model would require a far 
> more complex scheme of frame completion than is used now: wait for all taks, 
> then finalize all objects, then free all memory.

No, that would impose no problem. It is not required that the caller of
Finalize be the object's task. It is only required that it can be *any*
task, including the object's one.

> In your particular case, I don't understand why you don't use nesting to 
> solve the problem. That is, put the objectinside of the task (either 
> directly or logically), so it can be destroyed when the task needs to do 
> that. That would look something like:
> 
>    task type Device;
> 
>   task type Device is
>       Device_Data : not null access Device_Data_Type := new 
> Device_Data_Type;
>   begin
>       ...
>       Free (Device_Data);
>   end Device;
> 
> Note: you'd need a named access type to actually do this - I used an 
> anonymous one simply to make my point clearer.

Unfortunately that does not work. I simplified the task description.
Actually in my case the device has some associated objects, say, screws.
They are reference counted, both the devices and screws. A device screw
holds a reference to its device. The screws are used somewhere in the
application. You can create and remove screws and devices. The application
may hold references them.

Now consider a case when the last screw is removed from the device. This is
an operation eventually serviced by the device driver. I.e. within the
device driver, you see, it was the last screw of the device and *if* there
is no other references to the device, it must fall apart. This is a case
where you wanted the device to commit suicide. There is nobody else out
there to do this. The device is dangling. This is not the only use case,
just one possible case.

And, considering the design. It looks logical that if screws are ultimately
removed at some dedicated context (of the device driver), then the devices
themselves could also be removed on the context of some "collector task". 

Nevertheless, I am not sure that all cases where active objects should
"commit suicide", should/could be treated this way.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



  reply	other threads:[~2009-11-18  8:41 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-11-17 10:17 Tail recursion upon task destruction Dmitry A. Kazakov
2009-11-17 21:38 ` Randy Brukardt
2009-11-18  8:41   ` Dmitry A. Kazakov [this message]
2009-11-18 10:31     ` stefan-lucks
2009-11-18 17:48       ` Dmitry A. Kazakov
2009-11-19  9:25       ` Egil Høvik
2009-11-18 11:02     ` Georg Bauhaus
2009-11-18 13:29       ` Dmitry A. Kazakov
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox