Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2010-06

Multiple LCL instances

12 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Michael Schnell

There were several discussions, that when doing a DLL or .so with Lazarus and using same with a Lazarus project, it's an issue that the DLL will create it's own LCL "application" instance and thus you can't easily do "normal" GUI stuff in the DLL/.so. I seem to remember that there is a possible workaround by passing the main program's application's pointer to the called instance (or something like that). With Delphi you can use a "runtime package" that seems to do this automatically rather than a DLL.

Now I'm interested in the contrary:

Is there a decent way to create multiple instances of the LCL "application" and/or GUI interface to allow for an application that has multiple independent "main forms" (each with it's own main thread), i.e. something like multiple applications that share a common memory space (and heap management). The goal is to create a complex application that in one window needs to show rather complex GUI informations that come in from some threads and are passed towards the main thread and thus permanently generate heavy LCL activity and on another window some user interaction should be handled in a timely way (rather than being blocked by activity done in the other Window). Starting from some level of complexity, simply doing "Application.ProcessMessages" is not enough any more as (1) this introduces additional overhead slowing down things even more and (2) with modern multi-core PCs, this does not allow the concurrent frames to use multiple CPUs which would greatly optimize the LCL operations.

-Michael

Reply by email

Mark Morgan Lloyd
to Michael Schnell
Michael Schnell wrote
Is there a decent way to create multiple instances of the LCL "application" and/or GUI interface to allow for an application that has multiple independent "main forms" (each with it's own main thread),

I wonder whether this would be better handled by having multiple application instances with suitable interprocess communication, i.e. like Netscape/Mozilla's XPCOM.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Mattias Gaertner
to Michael Schnell: There were several discussions, that when doing a DLL or .so with Lazarus and using same…
Show quoted text 26 lines
There were several discussions, that when doing a DLL or .so with Lazarus and using same with a Lazarus project, it's an issue that the DLL will create it's own LCL "application" instance and thus you can't easily do "normal" GUI stuff in the DLL/.so. I seem to remember that there is a possible workaround by passing the main program's application's pointer to the called instance (or something like that). With Delphi you can use a "runtime package" that seems to do this automatically rather than a DLL. Now I'm interested in the contrary: Is there a decent way to create multiple instances of the LCL "application" and/or GUI interface to allow for an application that has multiple independent "main forms" (each with it's own main thread), i.e. something like multiple applications that share a common memory space (and heap management). The goal is to create a complex application that in one window needs to show rather complex GUI informations that come in from some threads and are passed towards the main thread and thus permanently generate heavy LCL activity and on another window some user interaction should be handled in a timely way (rather than being blocked by activity done in the other Window). Starting from some level of complexity, simply doing "Application.ProcessMessages" is not enough any more as (1) this introduces additional overhead slowing down things even more and (2) with modern multi-core PCs, this does not allow the concurrent frames to use multiple CPUs which would greatly optimize the LCL operations.

The LCL uses various global variables.
It is better to use multiple processes and communicate between them, e.g. via simpleipc.

Mattias

Reply by email

Michael Schnell
to Mark Morgan Lloyd: I wonder whether this would be better handled by having multiple application instances…
Mark Morgan Lloyd wrote
I wonder whether this would be better handled by having multiple application instances with suitable interprocess communication, i.e. like Netscape/Mozilla's XPCOM.

Technically I agree that this in fact asks for multiple Applications - even though I have the impression that as well Windows as GTK allows for using multiple (kind of) main Forms with a single application *). For the programmer I would wish for having him work in a more "integrated" environment than doing two separate applications and manually code any communication between them. Maybe a framework that organizes the communication under the hood might be a way to go.

-Michael

*)
Windows: MadShi for Delphi seems to allow for creating an additional message queue in an application (I did not test this) I don't see why GTK should only allow for attaching a single GUI interface instance to an application.

Reply by email

Michael Schnell
to Mattias Gaertner: On Fri, 11 Jun 2010 10:23:36 +0200 The LCL uses various global variables. It is better to…
Mattias Gaertner wrote
The LCL uses various global variables.

That of course will prevent creating multiple instances. (In fact a shortcoming of the current design, but of course multiple "application"/GUI instances might be a rarely requested feature.)

But if the parts are linked separately (e.g. when doing a DLL / .so) the global variables will exist with each instance, while the memory space is shared and it should be possible to use a common heap, so that access to instances of all classes should be possible from the "main"-threads attached to any instance of the LCL.

OTOH, it might be possible to hook to the address space of another process to share the heap and thus all instances of user defined classes. Madshi's "MadRemote" seems to do something like this for Delphi/Windows.

-Michael

Reply by email

Mark Morgan Lloyd
to Michael Schnell: Technically I agree that this in fact asks for multiple Applications - even though I have…
Michael Schnell wrote 7 lines
Technically I agree that this in fact asks for multiple Applications - even though I have the impression that as well Windows as GTK allows for using multiple (kind of) main Forms with a single application *). For the programmer I would wish for having him work in a more "integrated" environment than doing two separate applications and manually code any communication between them. Maybe a framework that organizes the communication under the hood might be a way to go.

The really important thing is not to kill performance for the sake of "good design", something that I think both Mozilla (compared with Netscape) and KDE (compared with older versions) stand guilty of. As a very low priority background project I'm thinking about something which would synchronise multiple apps and possibly multiple users to do a particular job, this would be very much tree-structured with a database backend. [The market leader is strictly single-user, in fact the user can't open up multiple windows let alone spread his workload over different computers. However in this case synchronisation would be by a work queue on the backend, i.e. it would need nothing like the bandwidth of a single integrated application.]

Windows: MadShi for Delphi seems to allow for creating an additional message queue in an application (I did not test this)

Interesting that both you and Mattias are on the same track.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Marco van de Voort
to Michael Schnell: That of course will prevent creating multiple instances. (In fact a shortcoming of the…
Michael Schnell wrote 5 lines
OTOH, it might be possible to hook to the address space of another process to share the heap and thus all instances of user defined classes. Madshi's "MadRemote" seems to do something like this for Delphi/Windows.

That only fixes the memorymanager issue, not the fact that there are two copies of RTL/FCL/LCL state. (and VMTs for all duplicate classes etc).

It can be a workaround, but then you have to be very careful. And that is not "easy".

Reply by email

Michael Schnell
to Marco van de Voort
Marco van de Voort wrote
That only fixes the memorymanager issue, not the fact that there are two copies of RTL/FCL/LCL state. (and VMTs for all duplicate classes etc).

OK.

Do you suggest that the LCL that seemingly automatically is created and initialized in the DLL/.so in fact does work concurrently with the one created by the application itself ?

Say, you create an application that creates a TForm and a TTimer showing a counter on the form and then initializes a DLL/.so that also creates it's own TForm and it's own TTimer showing a counter on the DLL/.so's TForm, but otherwise the process and the DLL don't you think this application could be configured in a way that both TForms are shown side-by-side and can be individually moved using the mouse ?

This in fact could be a good starting point.

It can be a workaround, but then you have to be very careful.

If now the said "memory manager workaround" would allow for the DLL to work with the instances of the (non-GUI) user defined classes that are used to manage the internal "business-logic" application data, and synchronization issues can be taken care of by TCriticalSection (or whatever), this could be the way to go,

And that is not "easy".

That is not required. If you suggest that it could be made working. We might start some testing on that behalf.

Thanks a lot !
-Michael

Reply by email

Marco van de Voort
to Michael Schnell
Michael Schnell wrote 7 lines
> That only fixes the memorymanager issue, not the fact that there are two > copies of RTL/FCL/LCL state. (and VMTs for all duplicate classes etc). OK. Do you suggest that the LCL that seemingly automatically is created and initialized in the DLL/.so in fact does work concurrently with the one created by the application itself ?

Yes. And I thought I told you this already several times (on lazarusforum.de)

Currently there is no acceptable way to do shared libs with FPC/Lazarus. All is hackery/wizardry which might stop at any time.

Show quoted text 7 lines
Say, you create an application that creates a TForm and a TTimer showing a counter on the form and then initializes a DLL/.so that also creates it's own TForm and it's own TTimer showing a counter on the DLL/.so's TForm, but otherwise the process and the DLL don't communicate at all. Do you think this application could be configured in a way that both TForms are shown side-by-side and can be individually moved using the mouse ?

I think this is not a sane scenario that is workable. People in a hurry might mess with it now because there is nothing else, but this is not a supportable solution.

Show quoted text 5 lines
If now the said "memory manager workaround" would allow for the DLL to work with the instances of the (non-GUI) user defined classes that are used to manage the internal "business-logic" application data, and synchronization issues can be taken care of by TCriticalSection (or whatever), this could be the way to go,

People can hack, mess and try. But there is no supportable solution there.

Knowledgable people that understand the RTL and LCL architecture can make all kinds of hacks, but there is nothing to recommend to sb who doesn't have that knowledgable.

Show quoted text 5 lines
> And that is > not "easy". > That is not required. If you suggest that it could be made working. We might start some testing on that behalf.

I wouldn't waste time on that. Do it well (packages) or not.

Reply by email

Michael Schnell
to Marco van de Voort
Marco van de Voort wrote
I wouldn't waste time on that. Do it well (packages) or not.

Thanks a lot for your suggestions!

Unfortunately there is no way to "do it well" right now. AFAIK, there is no predefined way to create applications with multiple (kind of) "main windows" yet. And supposedly there is not much request for such nowadays, as applications so "demanding" as my colleagues are doing, are quite seldom made in Pascal. I am just researching some way for them to "do it well".

There are several options. The ones I found that seem "well" out off the box are (1) doing multiple applications and manually code the communication between them and (2) coding the additional "main windows" manually using the OS GUI APIs, instead of using the LCL.

The "hacks" include (1) doing multiple applications and modify the heap management to have them use a common heap in a shared memory region to allow for commonly used Pascal object and (2) to use a DLL/SO to allow for multiple "main windows" / LCLs in a single memory space.

Regarding that any "creative" decent solution at some time was started as a hack, we will see where we get :).

-Michael

Reply by email

Razvan Adrian Bogdan
to Michael Schnell
Michael Schnell wrote 7 lines
The "hacks" include (1) doing multiple applications and modify the heap management to have them use a common heap in a shared memory region to allow for commonly used Pascal object and (2) to use a DLL/SO to allow for multiple "main windows" / LCLs in a single memory space. Regarding that any "creative" decent solution at some time was started as a hack, we will see where we get :).

Does this mean something like FastShareMem is possible ?

Razvan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20100616/efc375d7/attachment.html>

Reply by email