comp.lang.ada
 help / color / mirror / Atom feed
* controlled constant_reference type?
@ 2018-03-14  8:55 Stephen Leake
  2018-03-14 10:49 ` Alejandro R. Mosteo
  2018-03-14 22:46 ` Randy Brukardt
  0 siblings, 2 replies; 3+ messages in thread
From: Stephen Leake @ 2018-03-14  8:55 UTC (permalink / raw)


I'm trying to create a protected vector container, that automatically provides task-safe access.

I'm having trouble with GNAT GPL 2017 not finalizing a read lock object, and I'm wondering if this is a compiler error.

Summary of the code in package gen_vectors-gen_protected:

   type Vector is new Ada.Finalization.Controlled with private
   with
      Constant_Indexing => Constant_Reference,
      Variable_Indexing => Variable_Reference,
      Iterator_Element  => Element_Type;


   protected type Guard is

      entry Acquire_Read;
      --  Available when there is no writer.

      procedure Release_Read;

      entry Acquire_Write;
      --  Available when there are no readers, and no writer.

      procedure Release_Write;

      --  It is tempting to provide an operation "update_read_to_write", so
      --  we spend as little time as possible with a write lock. But that
      --  leads to deadlock, if two tasks aquire read lock, then both attempt
      --  to upgrade.

      function Any_Readers_Or_Writers return Boolean;

   private
      Readers : Integer := 0;
      Writer  : Boolean := False;
   end Guard;

   type Vector is new Ada.Finalization.Controlled with record
      Super : Gen_Unbounded_Definite_Vectors.Vector;

      Guard : Guard_Access;
      --  We use an access type here for two reasons:
      --  1 - it allows Vector to be non-limited
      --  2 - it allows writing to Guard when the Vector object is 'in'.
   end record;

   type Read_Lock_Type (Container : not null access constant Vector)
     is new Ada.Finalization.Controlled with
   record
      Initialized : Boolean := False;
      --  Enforce Initialize called only once (sometimes it's hard to tell
      --  if Initialize will be called automatically).

      Finalized : Boolean := False;
      --  Finalize can be called more than once; don't release the guard
      --  more than once.
   end record;

   overriding procedure Initialize (Lock : in out Read_Lock_Type);
   --  Acquire read lock.

   overriding procedure Adjust (Lock : in out Read_Lock_Type);
   --  Acquire read lock again, since both copies will be Finalized.

   overriding procedure Finalize (Lock : in out Read_Lock_Type);
   --  Release read lock.

   type Constant_Reference_Type
     (Element   : not null access constant Element_Type;
      Container : not null access constant Vector)
     is record
      Lock : Read_Lock_Type (Container);
   end record;

Now, when I use Constant_Reference in a client package:

declare
   K : Syntax_Trees.Node renames Children (I);
   Child_Byte_Region : constant Buffer_Region :=
      Tree.Terminals (K.Terminal).Byte_Region;
begin
   ...
end;

Tree.Terminals is a Protected vector; when Child_Byte_Region is set, a temporary Constant_Reference_Type object is created; it should live only as long as needed to copy the data to Child_Byte_Region. However, Read_Lock_Type Initialize is called twice (once for an intermediate copy; I'm compiling with low optimizations for debugging), Finalize only once. This leaves the Tree.Terminals Guard locked with Readers = 1.

Even after the block exits, Guard is still locked.

I have a similar problem with an Iterator; it locks the Guard while the loop is executing, but leaves it locked when the loop exits.

Should this work, or is there something about Constant_Indexing that forbids Controlled (in which case there ought to be a compile time error)?

-- Stephe

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-03-14 22:46 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-14  8:55 controlled constant_reference type? Stephen Leake
2018-03-14 10:49 ` Alejandro R. Mosteo
2018-03-14 22:46 ` Randy Brukardt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox