This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] Requeue with abort from a timed-out entry call.


A requeue allows an accept statement to be completed by a different entry
call, possibly on a different task. If the requeue is abortable, it may
time out while queued on the second task, in which case the original timed
entry call must be aborted. This path handles the unusual case where the
timeout occurs before the requeue has taken place, when the accept statement
itself exceeds the specified delay. This case must be detected before the
requeue takes place, and handled like a conditional entry call, to prevent
arbitrarily long delays.

Execution of timed_entry_call below must produce the following output:

Round 1
E1 accepted
E1 requeued
First time aborting because E2 not ready
E2 ready
E2 accepted
E2 done

Round 2
E1 accepted
E1 requeued
E2 accepted
E1 done

Done

--
with Ada.Text_IO;
use  Ada.Text_IO;

procedure Timed_Entry_Call is

  task Server is
    entry E1;
  end Server;

  task Hidden is
    entry Start;
    entry E2;
  end Hidden;

  task W;

  task body W is
  begin
    Hidden.E2;
    Put_Line ("E2 done");
  end W;

  task body Server is
  begin
    loop
      accept E1 do
        Put_Line ("E1 accepted");
        delay 3.0;  -- (1) do some work that takes longer than client's patience
        Put_Line ("E1 requeued");
        requeue Hidden.E2 with abort;
      end E1;
    end loop;
  end Server;

  task body Hidden is
  begin
    accept Start;
    Put_Line ("E2 ready");
    loop
      accept E2 do
        Put_Line ("E2 accepted");
      end E2;
    end loop;
  end Hidden;

begin

  for I in 1 .. 2 loop

    Put_Line ("Round" & Integer'Image (I));

    select
      Server.E1;  -- E1 is ready for rendezvous
      Put_Line ("E1 done");
    or
      delay 1.0;  -- (2)
      Put_Line ("First time aborting because E2 not ready");
      Hidden.Start;  -- Make E2 ready for second time
    end select;

    delay 1.0;

    New_Line;

  end loop;

  Put_Line ("Done");

  abort Server, Hidden;

end Timed_Entry_Call;

Tested on x86_64-pc-linux-gnu, committed on trunk

2009-04-24  Ed Schonberg  <schonberg@adacore.com>

	* s-tasren.adb (Task_Do_Or_Queue): If a timed entry call is being
	requeued and the delay has expired while within the accept statement
	that executes the requeue, do not perform the requeue and indicate that
	the timed call has been aborted.

Attachment: difs
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]