------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                 S Y S T E M . S H A R E D _ M E M O R Y                  --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1998-2022, Free Software Foundation, Inc.         --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
--                                                                          --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception,   --
-- version 3.1, as published by the Free Software Foundation.               --
--                                                                          --
-- You should have received a copy of the GNU General Public License and    --
-- a copy of the GCC Runtime Library Exception along with this program;     --
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
-- <http://www.gnu.org/licenses/>.                                          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Ada.IO_Exceptions;
with Ada.Streams;
with Ada.Streams.Stream_IO;

with System.Global_Locks;
with System.Soft_Links;

with System.CRTL;
with System.File_Control_Block;
with System.File_IO;
with System.HTable;

with Ada.Unchecked_Deallocation;
with Ada.Unchecked_Conversion;

package body System.Shared_Storage is

   package AS renames Ada.Streams;

   package IOX renames Ada.IO_Exceptions;

   package FCB renames System.File_Control_Block;

   package SFI renames System.File_IO;

   package SIO renames Ada.Streams.Stream_IO;

   type String_Access is access String;
   procedure Free is new Ada.Unchecked_Deallocation
     (Object => String, Name => String_Access);

   Dir : String_Access;
   --  Holds the directory

   ------------------------------------------------
   -- Variables for Shared Variable Access Files --
   ------------------------------------------------

   Max_Shared_Var_Files : constant := 20;
   --  Maximum number of lock files that can be open

   Shared_Var_Files_Open : Natural := 0;
   --  Number of shared variable access files currently open

   type File_Stream_Type is new AS.Root_Stream_Type with record
      File : SIO.File_Type;
   end record;
   type File_Stream_Access is access all File_Stream_Type'Class;

   procedure Read
     (Stream : in out File_Stream_Type;
      Item   : out AS.Stream_Element_Array;
      Last   : out AS.Stream_Element_Offset);

   procedure Write
     (Stream : in out File_Stream_Type;
      Item   : AS.Stream_Element_Array);

   subtype Hash_Header is Natural range 0 .. 30;
   --  Number of hash headers, related (for efficiency purposes only) to the
   --  maximum number of lock files.

   type Shared_Var_File_Entry;
   type Shared_Var_File_Entry_Ptr is access Shared_Var_File_Entry;

   type Shared_Var_File_Entry is record
      Name : String_Access;
      --  Name of variable, as passed to Read_File/Write_File routines

      Stream : File_Stream_Access;
      --  Stream_IO file for the shared variable file

      Next : Shared_Var_File_Entry_Ptr;
      Prev : Shared_Var_File_Entry_Ptr;
      --  Links for LRU chain
   end record;

   procedure Free is new Ada.Unchecked_Deallocation
     (Object => Shared_Var_File_Entry,
      Name   => Shared_Var_File_Entry_Ptr);

   procedure Free is new Ada.Unchecked_Deallocation
     (Object => File_Stream_Type'Class,
      Name   => File_Stream_Access);

   function To_AFCB_Ptr is
     new Ada.Unchecked_Conversion (SIO.File_Type, FCB.AFCB_Ptr);

   LRU_Head : Shared_Var_File_Entry_Ptr;
   LRU_Tail : Shared_Var_File_Entry_Ptr;
   --  As lock files are opened, they are organized into a least recently
   --  used chain, which is a doubly linked list using the Next and Prev
   --  fields of Shared_Var_File_Entry records. The field LRU_Head points
   --  to the least recently used entry, whose prev pointer is null, and
   --  LRU_Tail points to the most recently used entry, whose next pointer
   --  is null. These pointers are null only if the list is empty.

   function Hash  (F : String_Access)      return Hash_Header;
   function Equal (F1, F2 : String_Access) return Boolean;
   --  Hash and equality functions for hash table

   package SFT is new System.HTable.Simple_HTable
     (Header_Num => Hash_Header,
      Element    => Shared_Var_File_Entry_Ptr,
      No_Element => null,
      Key        => String_Access,
      Hash       => Hash,
      Equal      => Equal);

   --------------------------------
   -- Variables for Lock Control --
   --------------------------------

   Global_Lock : Global_Locks.Lock_Type;

   Lock_Count : Natural := 0;
   --  Counts nesting of lock calls, 0 means lock is not held

   -----------------------
   -- Local Subprograms --
   -----------------------

   procedure Initialize;
   --  Called to initialize data structures for this package.
   --  Has no effect except on the first call.

   procedure Enter_SFE (SFE : Shared_Var_File_Entry_Ptr; Fname : String);
   --  The first parameter is a pointer to a newly allocated SFE, whose
   --  File field is already set appropriately. Fname is the name of the
   --  variable as passed to Shared_Var_RFile/Shared_Var_WFile. Enter_SFE
   --  completes the SFE value, and enters it into the hash table. If the
   --  hash table is already full, the least recently used entry is first
   --  closed and discarded.

   function Retrieve (File : String) return Shared_Var_File_Entry_Ptr;
   --  Given a file name, this function searches the hash table to see if
   --  the file is currently open. If so, then a pointer to the already
   --  created entry is returned, after first moving it to the head of
   --  the LRU chain. If not, then null is returned.

   function Shared_Var_ROpen (Var : String) return SIO.Stream_Access;
   --  As described above, this routine returns null if the
   --  corresponding shared storage does not exist, and otherwise, if
   --  the storage does exist, a Stream_Access value that references
   --  the shared storage, ready to read the current value.

   function Shared_Var_WOpen (Var : String) return SIO.Stream_Access;
   --  As described above, this routine returns a Stream_Access value
   --  that references the shared storage, ready to write the new
   --  value. The storage is created by this call if it does not
   --  already exist.

   procedure Shared_Var_Close (Var : SIO.Stream_Access);
   --  This routine signals the end of a read/assign operation. It can
   --  be useful to embrace a read/write operation between a call to
   --  open and a call to close which protect the whole operation.
   --  Otherwise, two simultaneous operations can result in the
   --  raising of exception Data_Error by setting the access mode of
   --  the variable in an incorrect mode.

   ---------------
   -- Enter_SFE --
   ---------------

   procedure Enter_SFE (SFE : Shared_Var_File_Entry_Ptr; Fname : String) is
      Freed : Shared_Var_File_Entry_Ptr;

   begin
      SFE.Name := new String'(Fname);

      --  Release least recently used entry if we have to

      if Shared_Var_Files_Open = Max_Shared_Var_Files then
         Freed := LRU_Head;

         if Freed.Next /= null then
            Freed.Next.Prev := null;
         end if;

         LRU_Head := Freed.Next;
         SFT.Remove (Freed.Name);
         SIO.Close (Freed.Stream.File);
         Free (Freed.Name);
         Free (Freed.Stream);
         Free (Freed);

      else
         Shared_Var_Files_Open := Shared_Var_Files_Open + 1;
      end if;

      --  Add new entry to hash table

      SFT.Set (SFE.Name, SFE);

      --  Add new entry at end of LRU chain

      if LRU_Head = null then
         LRU_Head := SFE;
         LRU_Tail := SFE;

      else
         SFE.Prev := LRU_Tail;
         LRU_Tail.Next := SFE;
         LRU_Tail := SFE;
      end if;
   end Enter_SFE;

   -----------
   -- Equal --
   -----------

   function Equal (F1, F2 : String_Access) return Boolean is
   begin
      return F1.all = F2.all;
   end Equal;

   ----------
   -- Hash --
   ----------

   function Hash (F : String_Access) return Hash_Header is
      N : Natural := 0;

   begin
      --  Add up characters of name, mod our table size

      for J in F'Range loop
         N := (N + Character'Pos (F (J))) mod (Hash_Header'Last + 1);
      end loop;

      return N;
   end Hash;

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize is
      procedure Get_Env_Value_Ptr (Name, Length, Ptr : Address);
      pragma Import (C, Get_Env_Value_Ptr, "__gnat_getenv");

      subtype size_t is CRTL.size_t;

      procedure Strncpy (dest, src : System.Address; n : size_t)
        renames CRTL.strncpy;

      Dir_Name : aliased constant String :=
                   "SHARED_MEMORY_DIRECTORY" & ASCII.NUL;

      Env_Value_Ptr : aliased Address;
      Env_Value_Len : aliased Integer;

   begin
      if Dir = null then
         Get_Env_Value_Ptr
           (Dir_Name'Address, Env_Value_Len'Address, Env_Value_Ptr'Address);

         Dir := new String (1 .. Env_Value_Len);

         if Env_Value_Len > 0 then
            Strncpy (Dir.all'Address, Env_Value_Ptr, size_t (Env_Value_Len));
         end if;

         System.Global_Locks.Create_Lock (Global_Lock, Dir.all & "__lock");
      end if;
   end Initialize;

   ----------
   -- Read --
   ----------

   procedure Read
     (Stream : in out File_Stream_Type;
      Item   : out AS.Stream_Element_Array;
      Last   : out AS.Stream_Element_Offset)
   is
   begin
      SIO.Read (Stream.File, Item, Last);

   exception when others =>
      Last := Item'Last;
   end Read;

   --------------
   -- Retrieve --
   --------------

   function Retrieve (File : String) return Shared_Var_File_Entry_Ptr is
      SFE : Shared_Var_File_Entry_Ptr;

   begin
      Initialize;
      SFE := SFT.Get (File'Unrestricted_Access);

      if SFE /= null then

         --  Move to head of LRU chain

         if SFE = LRU_Tail then
            null;

         elsif SFE = LRU_Head then
            LRU_Head := LRU_Head.Next;
            LRU_Head.Prev := null;

         else
            SFE.Next.Prev := SFE.Prev;
            SFE.Prev.Next := SFE.Next;
         end if;

         SFE.Next := null;
         SFE.Prev := LRU_Tail;
         LRU_Tail.Next := SFE;
         LRU_Tail := SFE;
      end if;

      return SFE;
   end Retrieve;

   ----------------------
   -- Shared_Var_Close --
   ----------------------

   procedure Shared_Var_Close (Var : SIO.Stream_Access) is
      pragma Warnings (Off, Var);

   begin
      System.Soft_Links.Unlock_Task.all;
   end Shared_Var_Close;

   ---------------------
   -- Shared_Var_Lock --
   ---------------------

   procedure Shared_Var_Lock (Var : String) is
      pragma Warnings (Off, Var);

   begin
      System.Soft_Links.Lock_Task.all;
      Initialize;

      if Lock_Count /= 0 then
         Lock_Count := Lock_Count + 1;
         System.Soft_Links.Unlock_Task.all;

      else
         Lock_Count := 1;
         System.Soft_Links.Unlock_Task.all;
         System.Global_Locks.Acquire_Lock (Global_Lock);
      end if;

   exception
      when others =>
         System.Soft_Links.Unlock_Task.all;
         raise;
   end Shared_Var_Lock;

   ----------------------
   -- Shared_Var_Procs --
   ----------------------

   package body Shared_Var_Procs is

      use type SIO.Stream_Access;

      ----------
      -- Read --
      ----------

      procedure Read is
         S : SIO.Stream_Access := null;
      begin
         S := Shared_Var_ROpen (Full_Name);
         if S /= null then
            Typ'Read (S, V);
            Shared_Var_Close (S);
         end if;
      end Read;

      ------------
      -- Write --
      ------------

      procedure Write is
         S : SIO.Stream_Access := null;
      begin
         S := Shared_Var_WOpen (Full_Name);
         Typ'Write (S, V);
         Shared_Var_Close (S);
         return;
      end Write;

   end Shared_Var_Procs;

   ----------------------
   -- Shared_Var_ROpen --
   ----------------------

   function Shared_Var_ROpen (Var : String) return SIO.Stream_Access is
      SFE : Shared_Var_File_Entry_Ptr;

      use type Ada.Streams.Stream_IO.File_Mode;

   begin
      System.Soft_Links.Lock_Task.all;
      SFE := Retrieve (Var);

      --  Here if file is not already open, try to open it

      if SFE = null then
         declare
            S : aliased constant String := Dir.all & Var;

         begin
            SFE := new Shared_Var_File_Entry;
            SFE.Stream := new File_Stream_Type;
            SIO.Open (SFE.Stream.File, SIO.In_File, Name => S);
            SFI.Make_Unbuffered (To_AFCB_Ptr (SFE.Stream.File));

            --  File opened successfully, put new entry in hash table. Note
            --  that in this case, file is positioned correctly for read.

            Enter_SFE (SFE, Var);

            exception
               --  If we get an exception, it means that the file does not
               --  exist, and in this case, we don't need the SFE and we
               --  return null;

               when IOX.Name_Error =>
                  Free (SFE);
                  System.Soft_Links.Unlock_Task.all;
                  return null;
         end;

      --  Here if file is already open, set file for reading

      else
         if SIO.Mode (SFE.Stream.File) /= SIO.In_File then
            SIO.Set_Mode (SFE.Stream.File, SIO.In_File);
            SFI.Make_Unbuffered (To_AFCB_Ptr (SFE.Stream.File));
         end if;

         SIO.Set_Index (SFE.Stream.File, 1);
      end if;

      return SIO.Stream_Access (SFE.Stream);

   exception
      when others =>
         System.Soft_Links.Unlock_Task.all;
         raise;
   end Shared_Var_ROpen;

   -----------------------
   -- Shared_Var_Unlock --
   -----------------------

   procedure Shared_Var_Unlock (Var : String) is
      pragma Warnings (Off, Var);

   begin
      System.Soft_Links.Lock_Task.all;
      Initialize;
      Lock_Count := Lock_Count - 1;

      if Lock_Count = 0 then
         System.Global_Locks.Release_Lock (Global_Lock);
      end if;
      System.Soft_Links.Unlock_Task.all;

   exception
      when others =>
         System.Soft_Links.Unlock_Task.all;
         raise;
   end Shared_Var_Unlock;

   ----------------------
   -- Shared_Var_WOpen --
   ----------------------

   function Shared_Var_WOpen (Var : String) return SIO.Stream_Access is
      SFE : Shared_Var_File_Entry_Ptr;

      use type Ada.Streams.Stream_IO.File_Mode;

   begin
      System.Soft_Links.Lock_Task.all;
      SFE := Retrieve (Var);

      if SFE = null then
         declare
            S : aliased constant String := Dir.all & Var;

         begin
            SFE := new Shared_Var_File_Entry;
            SFE.Stream := new File_Stream_Type;
            SIO.Open (SFE.Stream.File, SIO.Out_File, Name => S);
            SFI.Make_Unbuffered (To_AFCB_Ptr (SFE.Stream.File));

         exception
            --  If we get an exception, it means that the file does not
            --  exist, and in this case, we create the file.

            when IOX.Name_Error =>

               begin
                  SIO.Create (SFE.Stream.File, SIO.Out_File, Name => S);

               exception
                  --  Error if we cannot create the file

                  when others =>
                     raise Program_Error with
                        "cannot create shared variable file for """ & S & '"';
               end;
         end;

         --  Make new hash table entry for opened/created file. Note that
         --  in both cases, the file is already in write mode at the start
         --  of the file, ready to be written.

         Enter_SFE (SFE, Var);

      --  Here if file is already open, set file for writing

      else
         if SIO.Mode (SFE.Stream.File) /= SIO.Out_File then
            SIO.Set_Mode (SFE.Stream.File, SIO.Out_File);
            SFI.Make_Unbuffered (To_AFCB_Ptr (SFE.Stream.File));
         end if;

         SIO.Set_Index (SFE.Stream.File, 1);
      end if;

      return SIO.Stream_Access (SFE.Stream);

   exception
      when others =>
         System.Soft_Links.Unlock_Task.all;
         raise;
   end Shared_Var_WOpen;

   -----------
   -- Write --
   -----------

   procedure Write
     (Stream : in out File_Stream_Type;
      Item   : AS.Stream_Element_Array)
   is
   begin
      SIO.Write (Stream.File, Item);
   end Write;

end System.Shared_Storage;
