From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Augmented active object pattern
Date: Wed, 18 Apr 2018 10:01:27 +0200
Date: 2018-04-18T10:01:27+02:00 [thread overview]
Message-ID: <pb6u0n$10q2$1@gioia.aioe.org> (raw)
The following is a way to have an encapsulated task (active object etc)
which hopefully works around most of the language issues.
type Object_Type;
task type Worker_Task (Owner : not null access Object_Type'Class) is
entry Quit;
... -- other entries
end Worker_Task;
type Worker_Ptr is access all Worker_Type;
type Object_Type is new Ada.Finalization.Limited_Controlled with
Worker : Worker_Ptr;
...
end record;
overriding procedure Finalize (Object : in out Object_Type);
This was the usual part.
----------------------------------------------------
task body Worker_Task is
begin
while Is_Callable (Environment_Task) loop
select
accept Quit;
exit;
or ... -- other entries
else -- or delay
null;
end select;
.. -- Doing a chunk of main job
end loop;
end Worker_Task;
procedure Finalize (Object : in out Object_Type) is
procedure Free is
new Ada.Unchecked_Deallocation (Worker_Task, Worker_Ptr);
begin
if Object.Worker /= null then
if Environment_Task /= Current_Task
Object.Worker.Quit; -- Request exiting
end if;
while not Object.Worker'Terminated loop
delay 0.001;
end loop;
Free (Object.Worker);
end if;
...
end Finalize;
-----------------------------------------------------
New here is handling the library level finalization deadlock. The task
terminates itself when the environment task is not "callable" emulating
forbidden terminate alternative for this special case. Below the library
level this does not work, so the Quit entry is needed to handle these as
before. In its part Quit does not work (deadlocks) at the master's level.
Within Finalize, we check if things happen on the library level. If not
we request task termination the usual way via entry call to Quit. At the
library level that would deadlock (thanks to RM 7.6.1(4)), so Quit is
not called and task terminates itself recognizing the special case
hidden in Annotated RM C.7.1(10) as a notice.
Note that when the pointer is declared below the library level the
deadlock reemerges and there is no solution to that whatsoever, because
the "callable trick" works exclusively for the environment task.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
reply other threads:[~2018-04-18 8:01 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox