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 <[email protected]>
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 <[email protected]>
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 <[email protected]> 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/gnoga-list
_______________________________________________
Gnoga-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gnoga-list
_______________________________________________
Gnoga-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gnoga-list