Assume the following record defined with a “method k” in a package:
type rec1_type is record
i : integer;
end record;
function k(rec1 : rec1_type) return Integer is (rec1.i + 1);
``
From "outside" this looks like a record with two components:
rec1.i and rec1.k (where rec1.k = rec1.i + 1)
Then assume a protected object with a function f with argument of type rec1_type:
function f(rec1 : rec1_type) return Integer is (2*rec1.k);
Hence f makes a call to k outside the protected object and the program "hangs".
Did I understand correctly? If so, have you any good advice what
I should do to avoid the progamme to hang?
reinert
Obs, the function k (in my real situation) calls back again to the protected object which is then blocked
reinert
(department of impulsive posting - but your response helped)
I think Ada forbids calling a potentially blocking call inside a protected operation, so if K blocks, then you can’t call it in F.
It’s hard to gen up a solution without a more complete example. In the above example you gave K doesn’t call back to the protected object. Can you flesh out the example a bit. In your example, K only pulls from the non protected rec1_type and we don’t know what the protected object looks like (or what the other function k calls looks like).
My first thought is that you shouldn’t need function F in the same protected object as the one K calls a function from. If you need another value via F then I would just add another function to the protected object and have k call those two functions separately and do the math unprotected. If instead you need access to rec1_type protected, I would create a separate mutex like protected object and protect rec1_type that way (otherwise you have the protected object of f doing two different jobs).
The background is that a protected action implementation may use a simple spin lock. If a call is not recognised as internal the implementation would try to lock again which would deadlock.
with Ada.Text_IO;
use Ada.Text_IO;
procedure Rktest1 is
function f_outside1 (i : Integer) return Integer;
protected po1 is
function f_inside1 (i : Integer) return Integer;
function f_inside2 (i : Integer) return Integer;
end po1;
protected body po1 is
function f_inside1 (i : Integer) return Integer is (f_outside1 (i));
function f_inside2 (i : Integer) return Integer is (i + 10);
end po1;
function f_outside1 (i : Integer) return Integer is (po1.f_inside2 (i));
begin
Put_Line ("Start");
Put_Line (po1.f_inside1 (5)'Image);
Put_Line ("Stop");
end Rktest1;
It hangs because f_outside1 makes an external call to po1.f_inside2 during a protected action initiated by po1.f_inside1.
ARM 9.5.1:
During a protected action, it is a bounded error to invoke an operation that is potentially blocking . The following are defined to be potentially blocking operations:
…
an external call on a protected subprogram (or an external requeue) with the same target object as that of the protected action;