Index: g-socket.adb =================================================================== --- g-socket.adb (revision 145689) +++ g-socket.adb (working copy) @@ -33,6 +33,7 @@ with Ada.Streams; use Ada.Streams; with Ada.Exceptions; use Ada.Exceptions; +with Ada.Finalization; with Ada.Unchecked_Conversion; with Interfaces.C.Strings; @@ -53,9 +54,6 @@ package body GNAT.Sockets is use type C.int; - Finalized : Boolean := False; - Initialized : Boolean := False; - ENOERROR : constant := 0; Empty_Socket_Set : Socket_Set_Type; @@ -242,6 +240,15 @@ package body GNAT.Sockets is -- it is added to the write set. If no selector is provided, a local one is -- created for this call and destroyed prior to returning. + type Sockets_Library_Controller is new Ada.Finalization.Limited_Controlled + with null record; + -- This type is used to generate automatic calls to Initialize and Finalize + -- during the elaboration and finalization of this package. A single object + -- of this type must exist at library level. + + procedure Initialize (X : in out Sockets_Library_Controller); + procedure Finalize (X : in out Sockets_Library_Controller); + --------- -- "+" -- --------- @@ -793,14 +800,24 @@ package body GNAT.Sockets is -- Finalize -- -------------- + procedure Finalize (X : in out Sockets_Library_Controller) is + pragma Unreferenced (X); + begin + -- Finalization operation for the GNAT.Sockets package + + Thin.Finalize; + end Finalize; + + -------------- + -- Finalize -- + -------------- + procedure Finalize is begin - if not Finalized - and then Initialized - then - Finalized := True; - Thin.Finalize; - end if; + -- This is a dummy placeholder for an obsolete API. + -- The real finalization actions are in Initialize primitive operation + -- of Sockets_Library_Controller. + null; end Finalize; --------- @@ -1218,6 +1235,7 @@ package body GNAT.Sockets is function Image (Item : Socket_Set_Type) return String is Socket_Set : Socket_Set_Type := Item; + begin declare Last_Img : constant String := Socket_Set.Last'Img; @@ -1225,9 +1243,11 @@ package body GNAT.Sockets is (1 .. (Integer (Socket_Set.Last) + 1) * Last_Img'Length); Index : Positive := 1; Socket : Socket_Type; + begin while not Is_Empty (Socket_Set) loop Get (Socket_Set, Socket); + declare Socket_Img : constant String := Socket'Img; begin @@ -1235,6 +1255,7 @@ package body GNAT.Sockets is Index := Index + Socket_Img'Length; end; end loop; + return "[" & Last_Img & "]" & Buffer (1 .. Index - 1); end; end Image; @@ -1281,6 +1302,20 @@ package body GNAT.Sockets is -- Initialize -- ---------------- + procedure Initialize (X : in out Sockets_Library_Controller) is + pragma Unreferenced (X); + begin + -- Initialization operation for the GNAT.Sockets package + + Empty_Socket_Set.Last := No_Socket; + Reset_Socket_Set (Empty_Socket_Set.Set'Access); + Thin.Initialize; + end Initialize; + + ---------------- + -- Initialize -- + ---------------- + procedure Initialize (Process_Blocking_IO : Boolean) is Expected : constant Boolean := not SOSC.Thread_Blocking_IO; @@ -1290,7 +1325,11 @@ package body GNAT.Sockets is "incorrect Process_Blocking_IO setting, expected " & Expected'Img; end if; - Initialize; + -- This is a dummy placeholder for an obsolete API. + -- Real initialization actions are in Initialize primitive operation + -- of Sockets_Library_Controller. + + null; end Initialize; ---------------- @@ -1299,12 +1338,10 @@ package body GNAT.Sockets is procedure Initialize is begin - if not Initialized then - Initialized := True; - Empty_Socket_Set.Last := No_Socket; - Reset_Socket_Set (Empty_Socket_Set.Set'Access); - Thin.Initialize; - end if; + -- This is a dummy placeholder for an obsolete API. + -- Real initialization actions are in Initialize primitive operation + -- of Sockets_Library_Controller. + null; end Initialize; -------------- @@ -2330,4 +2367,9 @@ package body GNAT.Sockets is end if; end Write; + Sockets_Library_Controller_Object : Sockets_Library_Controller; + pragma Unreferenced (Sockets_Library_Controller_Object); + -- The elaboration and finalization of this object perform the required + -- initialization and cleanup actions for the sockets library. + end GNAT.Sockets; Index: g-socket.ads =================================================================== --- g-socket.ads (revision 145744) +++ g-socket.ads (working copy) @@ -383,6 +383,8 @@ package GNAT.Sockets is -- Note that this operation is a no-op on UNIX platforms, but applications -- should make sure to call it if portability is expected: some platforms -- (such as Windows) require initialization before any socket operation. + -- This is now a no-op (initialization and finalization are done + -- automatically). procedure Initialize (Process_Blocking_IO : Boolean); pragma Obsolescent @@ -394,10 +396,14 @@ package GNAT.Sockets is -- is built. The old version of Initialize, taking a parameter, is kept -- for compatibility reasons, but this interface is obsolete (and if the -- value given is wrong, an exception will be raised at run time). + -- This is now a no-op (initialization and finalization are done + -- automatically). procedure Finalize; -- After Finalize is called it is not possible to use any routines -- exported in by this package. This procedure is idempotent. + -- This is now a no-op (initialization and finalization are done + -- automatically). type Socket_Type is private; -- Sockets are used to implement a reliable bi-directional point-to-point,