https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124191

            Bug ID: 124191
           Summary: Max_Entry_Queue_Length can not be specified for task
                    entries or task/protected types
           Product: gcc
           Version: 15.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: ada
          Assignee: unassigned at gcc dot gnu.org
          Reporter: liam at liampwll dot com
                CC: dkm at gcc dot gnu.org
  Target Milestone: ---

Created attachment 63740
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=63740&action=edit
WIP fix

RM22 D.4(17/5) specifies that the Max_Entry_Queue_Length aspect may be applied
to a "a task type (including the anonymous type of a single_task_declaration),
protected type (including the anonymous type of a
single_protected_declaration), or an entry_declaration". GNAT currently only
allows Max_Entry_Queue_Length on an entry declaration of a protected
type/object.

The attached patch still has some TODOs, but I don't want to spend too long on
it if this will get marked as a WONTFIX.

Notably the entire MEQL system found by searching for
Protected_Entry_Queue_Max_Array needs to be copied over to tasks.

As an aside, is there a formatter configuration for the code in GNAT? I've just
been basing my formatting on nearby code.

Reproducer follows:

with Ada.Text_IO; use Ada.Text_IO;

procedure Example is

   protected Worker
     with Max_Entry_Queue_Length => 4
   is
      entry Do_Work;
      procedure Unblock;
   private
      X : Boolean := False;
   end Worker;

   protected body Worker is
      entry Do_Work when X is
      begin
         Put_Line ("Do_Work'Count = " & Do_Work'Count'Image);
         delay 0.2;
      end Do_Work;

      procedure Unblock is
      begin
         X := True;
      end Unblock;
   end Worker;

   task type T with Max_Entry_Queue_Length => 4;

   task body T is
   begin
      Worker.Do_Work;
   exception
      when E : others =>
         Put_Line ("Task died");
   end T;

   Tasks : array (1 .. 10) of T;

   task T2 is
      entry Do_Nothing
      with Max_Entry_Queue_Length => 0;
   end T2;

   task body T2 is
   begin
      delay 10.0;
      accept Do_Nothing;
   end T2;
begin
   delay 1.0;
   Worker.Unblock;
   Worker.Do_Work;
   select
      T2.Do_Nothing;
   then abort
      T2.Do_Nothing;
   end select;
end Example;

Reply via email to