Ada 202x (24日目) - 'Index¶
休憩。 今までで一番短いです。
経緯¶
task
/protected
のマイナーな機能に複数 entry
をインデックスで区別するというものがあります。
ひとつの呼び出しがインデックス値によって各エントリに振り分けられます。
declare
task T is
entry Dispatch (Integer range 1 .. 3) (Parameter : in String);
end T;
task body T is
begin
accept Dispatch (1) (Parameter : in String) do
requeue Dispatch (2); -- たらい回し
end Dispatch;
accept Dispatch (2) (Parameter : in String) do
requeue Dispatch (3); -- 再びたらい回し
end Dispatch;
accept Dispatch (3) (Parameter : in String) do
Ada.Text_IO.Put_Line (Parameter);
end Dispatch;
end T;
begin
T.Dispatch (1) ("MESSAGE");
このインデックス値には名前が付いていません。 accept文の側は分かれていますのでAda 2005までは何も困らなかったのですが、Ada 2012からの事前条件/事後条件は仕様部側に書くことになります。 そのため実際に呼ばれているエントリの区別をつけることができませんでした。
Ada 202xでの改善¶
'Index¶
インデックス値を entry
の 'Index
属性として参照できるようになりました。
declare
use type Ada.Task_Identification.Task_Id;
task T is
entry Dispatch (Integer range 1 .. 3) (Parameter : in String)
with Pre =>
Dispatch'Index = 1
or else Ada.Task_Identification.Current_Task = T'Identity;
end T;
-- 以下省略
この例では T
は最初に 1
を待ちますのでいきなり 2
や 3
が呼ばれますとデッドロックします。
そのため外から呼ばれるときは 1
でなければならない、という事前条件を付けました。
pygmentsってテキトーですよね、と改めてしみじみと。
関連AI¶
AI12-0143-1 Using an entry index of a family in a precondition
AI12-0193-1 Postcondition failure for a task entry
所感¶
インデックス値付きのエントリは忘れられているぐらいマイナーという話でした。
synchronized interface
でも使えませんし。
Previous:
Ada 202x (23日目) - Stable_Properties
Next:
Ada 202x (25日目) - 契約と高階関数