Hi Pascal, Actually on second thoughts it's probably sufficient that I share the code for tutorial_03 I am using (a modified version of tutorial_03):
-- In the previous tutorials we created Singletons applications where there -- is no issue of concurrency outside of events from the same user. This -- allowed for programming in the familiar sequential patterns of regular -- console applications. In this tutorial we will create an application that -- will allow for multiple connections on the same machine, network or across -- the globe on the internet. -- -- In order to help see the different approach to setting up the application -- we will do something similar to the previous tutorial. with Ada.Exceptions; with Gnoga.Application.Multi_Connect; with Gnoga.Gui.Base; with Gnoga.Gui.Window; with Gnoga.Gui.View; with Gnoga.Gui.Element.Common; with Gnoga.Types; -- Gnoga special types are found in Gnoga.Types. procedure Tutorial_03 is -- Since this application will be used by multiple connections, we need to -- track and access that connection's specific data. To do this we create -- a derivative of Gnoga.Types.Connection_Data_Type that will be accessible -- to any object on a connection. type App_Data is new Gnoga.Types.Connection_Data_Type with record My_Window : Gnoga.Gui.Window.Pointer_To_Window_Class; My_View : Gnoga.Gui.View.View_Type; My_Button : Gnoga.Gui.Element.Common.Button_Type; My_Exit : Gnoga.Gui.Element.Common.Button_Type; end record; type App_Access is access all App_Data; procedure On_Click (Object : in out Gnoga.Gui.Base.Base_Type'Class); procedure On_Exit (Object : in out Gnoga.Gui.Base.Base_Type'Class); -- Events for our application. The implementation is almost identical -- to our previous tutorial. However we access the elements through our -- App_Data data structure associated with the connection instead of -- globally. procedure On_Click (Object : in out Gnoga.Gui.Base.Base_Type'Class) is App : constant App_Access := App_Access (Object.Connection_Data); begin App.My_View.New_Line; App.My_View.Put_Line ("I've been clicked!"); end On_Click; procedure On_Exit (Object : in out Gnoga.Gui.Base.Base_Type'Class) is App : constant App_Access := App_Access (Object.Connection_Data); View : Gnoga.Gui.View.View_Type; begin App.My_View.Remove; View.Create (App.My_Window.all); View.Put_Line ("Application exited."); App.My_Window.Close_Connection; Gnoga.Application.Multi_Connect.End_Application; exception when E : others => Gnoga.Log (Message => "On_Exit: " & Ada.Exceptions.Exception_Information (E)); end On_Exit; procedure On_Connect (Main_Window : in out Gnoga.Gui.Window.Window_Type'Class; Connection : access Gnoga.Application.Multi_Connect.Connection_Holder_Type); -- Instead of creating and setting up our GUI in the main body of the -- application, we now set up the GUI in a connection event handler. -- The implementation is almost identical to the last tutorial except we -- place our GUI element variables within the App_Data data structure -- that will be associated with the connection. procedure On_Connect (Main_Window : in out Gnoga.Gui.Window.Window_Type'Class; Connection : access Gnoga.Application.Multi_Connect.Connection_Holder_Type) is pragma Unreferenced (Connection); App : constant App_Access := new App_Data; begin App.My_Window := Main_Window'Unchecked_Access; Main_Window.Connection_Data (App); -- This associates our application data to this connection. Now any -- object created on it has access to it using its Connection_Data -- property. When the connection is done it will deallocate the memory -- used. App.My_View.Create (Main_Window); App.My_Button.Create (App.My_View, "Click Me!"); App.My_Button.On_Click_Handler (On_Click'Unrestricted_Access); App.My_Exit.Create (App.My_View, "Exit App"); App.My_Exit.On_Click_Handler (On_Exit'Unrestricted_Access); App.My_View.Horizontal_Rule; end On_Connect; begin Gnoga.Application.Title ("Tutorial 03"); Gnoga.Application.HTML_On_Close ("Application ended."); Gnoga.Application.Multi_Connect.Initialize; Gnoga.Application.Multi_Connect.On_Connect_Handler (Event => On_Connect'Unrestricted_Access, Path => "default"); -- With a Multi_Connect application it is possible to have different -- URL paths start different Connection Event Handlers. This allows -- for the creation of Web Apps that appear as larger web sites or as -- multiple applications to the user. Setting Path to "default" means -- that any unmatched URL path will start that event handler. A URL path -- is the path following the host and port. For example: -- http://localhost:8080/test/me -- The Path would be "/test/me". In Gnoga the path can even appear to be -- a file name "/test/me.html". However if you have a file of the same -- name in the html directory it will be served instead. Gnoga.Application.Multi_Connect.Message_Loop; end Tutorial_03; Best regards, Joakim ________________________________________ Från: Joakim Dahlgren Strandberg <joaki...@kth.se> Skickat: den 12 november 2019 00:09 Till: Gnoga support list Kopia: Pascal Ämne: Re: [Gnoga-list] Memory leak in Gnoga? False alarm? Hi Pascal, Thanks for improving the memory leak situation. Before I did "git pull" to get the latest commits the result of valgrind was: ==2851== ==2851== HEAP SUMMARY: ==2851== in use at exit: 17,592 bytes in 19 blocks ==2851== total heap usage: 574 allocs, 555 frees, 177,201 bytes allocated ==2851== And after the memory leak fix commits: ==4220== ==4220== HEAP SUMMARY: ==4220== in use at exit: 10,520 bytes in 15 blocks ==4220== total heap usage: 574 allocs, 559 frees, 177,201 bytes allocated ==4220== And so the situation has been improved. I will upload a reproducer on github tomorrow night to be able to reproduce my results. Too late to do it now. To be continued... Best regards, Joakim ________________________________________ Från: Pascal via Gnoga-list <gnoga-list@lists.sourceforge.net> Skickat: den 11 november 2019 19:12 Till: Gnoga support list Kopia: Pascal Ämne: Re: [Gnoga-list] Memory leak in Gnoga? False alarm? Hello Joakim, > Le 3 nov. 2019 à 23:25, Joakim Dahlgren Strandberg <joaki...@kth.se> a écrit : > > Hi Pascal, > > Thanks for the detailed analysis of the potential memory leak. Seems it was a > treasure trove of issues to look at. I suspected there may be something > suspicious with some code in Dmitry's Simple Components but the code I looked > at appeared correct. Looking forward to hear more about the progress on this. > If I find out more I will share it here on the Gnoga mailing list of course. > > Best regards, > Joakim > ________________________________________ ... > Hello Joakim, > > I have got detailed results from valgrind of memory leaks after Gnoga server > execution. > There is 4 kinds of them: > - allocation in globals that are not freed before exiting (Watchdog and > Gnoga_HTTP_Server) -> easy to fix Fix. > - allocation in GNAT RTE (initialization, Unbounded_String, String, > String_Access and exceptions) -> to be reported to AdaCore Done for Unbounded_String. > - allocation in HTTP server (container) -> to be reported to Dmitry Fix. > - allocation in Multi-Connect application for Connection_Data, user guide > said: > -- By default Connection_Data is assumed to be a dynamic object > -- and freed when the connection is closed. > but it seems not to be the case -> investigation is needed. Added a log: "Connection_Data freed", it seems then to be correct. Changes are commited: https://sourceforge.net/p/gnoga/code/ci/8bf88ff3c965689b2f097d1f4b0aab69cc75f9bd/ Could you please check with valgring if these leaks are still present or not? Thanks, Pascal. http://blady.pagesperso-orange.fr _______________________________________________ Gnoga-list mailing list Gnoga-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/gnoga-list _______________________________________________ Gnoga-list mailing list Gnoga-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/gnoga-list _______________________________________________ Gnoga-list mailing list Gnoga-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/gnoga-list