Sign in Join

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

Mailing lists / lazarus / 2013-04

FPC 2.6.2 + Thread.Queue?

30 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

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

silvioprog

Hi,

In FPC 2.7.1+ you've the Queue method, but it doesn't exists in FPC 2.6.2. So, what you uses instead it? The Synchronize method does not works in this case.

I'm implementing a small unit with some interfaces to use of sockets with TCP/IP protocol easily, and I need to set compatibility with stable FPC too. The temporary repository of it is:
https://bitbucket.org/silvioprog/tcpipcomp

Thank you,

Silvio Cl?cio My public projects - github.com/silvioprog -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20130423/86e0a4c8/attachment.html>

Reply by email

Michael Van Canneyt
to silvioprog
silvioprog wrote
Hi, In FPC 2.7.1+ you've the Queue method, but it doesn't exists in FPC 2.6.2. So, what you uses instead it? The Synchronize method does not works in this case.

To my knowledge, nothing is available.

Michael.

Reply by email

Michael Schnell
to Marco van de Voort
Marco van de Voort wrote 5 lines
On Tue, Apr 23, 2013 at 08:34:53PM -0300, silvioprog wrote: > In FPC 2.7.1+ you've the Queue method, but it doesn't exists in FPC 2.6.2. > So, what you uses instead it? The Synchronize method does not works in this > case. If Windows only, just use postmessage.

While Postmessage() / Procedure... message is supported in Linux as well, I would recommend to ignore this Windows.centric relict in the language and just use the completely platform independent and available since a long time QueueAsyncCall() method (which does not exist in Delphi).

-Michael

Reply by email

Michael Schnell
to silvioprog: In FPC 2.7.1+ you've the Queue method, but it doesn't exists in FPC 2.6.2. So, what you…
silvioprog wrote 10 lines
In FPC 2.7.1+ you've the Queue method, but it doesn't exists in FPC 2.6.2. So, what you uses instead it? The Synchronize method does not works in this case. I'm implementing a small unit with some interfaces to use of sockets with TCP/IP protocol easily, and I need to set compatibility with stable FPC too. The temporary repository of it is: https://bitbucket.org/silvioprog/tcpipcomp

I am very happy that the Delphi compatible and platform independent TThread.Queue() finally is supported by fpc/Lazarus.

OTOH since a long time we do have QueueAsyncCall() which does the same job, is more versatile (as it can pass parameters)m is platform independent (but does not exist in Delphi).

-Michael

Reply by email

Michael Van Canneyt
to Michael Schnell
Michael Schnell wrote 18 lines
On 04/24/2013 01:34 AM, silvioprog wrote: > > In FPC 2.7.1+ you've the Queue method, but it doesn't exists in FPC 2.6.2. > So, what you uses instead it? The Synchronize method does not works in this > case. > > I'm implementing a small unit with some interfaces to use of sockets with > TCP/IP protocol easily, and I need to set compatibility with stable FPC > too. The temporary repository of it is: > https://bitbucket.org/silvioprog/tcpipcomp > I am very happy that the Delphi compatible and platform independent TThread.Queue() finally is supported by fpc/Lazarus. OTOH since a long time we do have QueueAsyncCall() which does the same job, is more versatile (as it can pass parameters)m is platform independent (but does not exist in Delphi).

By contrast it works only in lazarus GUI programs, and is useless e.g. for daemons.

Michael.

Reply by email

Michael Schnell
to Michael Van Canneyt
Michael Van Canneyt wrote
By contrast it works only in lazarus GUI programs, and is useless e.g. for daemons.

Of course I do know that (as I issued the request for a "active" non-GUI "Widget Type" with support for a Pascal EventQueue for multiple platforms - like "mse" does provide ever since - already years ago, and even tried to implement it myself but failed due to the complexity of the Widget Type depending units in Lazarus).

But AFAIK same is true for TThread.Queue(), and TThread.Synchronize (requested by the OP).

-Michael

Reply by email

Sven Barth
to Michael Schnell
Michael Schnell wrote 13 lines
On 04/24/2013 10:41 AM, Michael Van Canneyt wrote: > > By contrast it works only in lazarus GUI programs, and is useless > e.g. for daemons. > Of course I do know that (as I issued the request for a "active" non-GUI "Widget Type" with support for a Pascal EventQueue for multiple platforms - like "mse" does provide ever since - already years ago, and even tried to implement it myself but failed due to the complexity of the Widget Type depending units in Lazarus). But AFAIK same is true for TThread.Queue(), and TThread.Synchronize (requested by the OP).

Both TThread.Queue and TThread.Synchronize just need calls to CheckSynchronize to be processed. Which is normally done by the widgetset event loop, but can be done manually as well (I'm using this for example in a highly threaded console application; the main thread there just calls CheckSynchronize while the rest is done in threads).

Regards,
Sven

Reply by email

Michael Van Canneyt
to Michael Schnell: Of course I do know that (as I issued the request for a "active" non-GUI "Widget Type"…
Michael Schnell wrote 13 lines
On 04/24/2013 10:41 AM, Michael Van Canneyt wrote: > > By contrast it works only in lazarus GUI programs, and is useless e.g. for > daemons. > Of course I do know that (as I issued the request for a "active" non-GUI "Widget Type" with support for a Pascal EventQueue for multiple platforms - like "mse" does provide ever since - already years ago, and even tried to implement it myself but failed due to the complexity of the Widget Type depending units in Lazarus). But AFAIK same is true for TThread.Queue(), and TThread.Synchronize (requested by the OP).

No, thos is not true.

Somewhere the main program loop must call checksynchronize, that is all.

Michael.

Reply by email

Michael Schnell
to Michael Van Canneyt
Michael Van Canneyt wrote
Somewhere the main program loop must call checksynchronize, that is all.

If that (i.e. doing a pseudo-queue in the user-code) is true for all platforms (which would mean that an EventQueue does exist and just is not polled automatically), I don't see why QueueAsyncCall() can't be handled in the same way.

-Michael

Reply by email

Michael Schnell
to Sven Barth: Both TThread.Queue and TThread.Synchronize just need calls to CheckSynchronize to be…
Sven Barth wrote 6 lines
Both TThread.Queue and TThread.Synchronize just need calls to CheckSynchronize to be processed. Which is normally done by the widgetset event loop, but can be done manually as well (I'm using this for example in a highly threaded console application; the main thread there just calls CheckSynchronize while the rest is done in threads).

Thus I would assume that CheckSynchronize also checks the QueueAsncCall() results. If not I would consider this a design glitch (which supposedly easily could be corrected).

(In fact I do have a rather versatile testing program for this stuff that I could easily extend to do tests with CheckSynchronize.)

-Michael

Reply by email

Michael Van Canneyt
to Michael Schnell: If that (i.e. doing a pseudo-queue in the user-code) is true for all platforms (which…
Michael Schnell wrote 9 lines
On 04/24/2013 11:21 AM, Michael Van Canneyt wrote: > > Somewhere the main program loop must call checksynchronize, that is all. > If that (i.e. doing a pseudo-queue in the user-code) is true for all platforms (which would mean that an EventQueue does exist and just is not polled automatically), I don't see why QueueAsyncCall() can't be handled in the same way.

Because it resides in the LCL and is inherently bound to a GUI. (horrible nogui widgetset tricks notwithstanding)

The RTL does not need a GUI.

Michael.

Reply by email

Sven Barth
to Michael Schnell: If that (i.e. doing a pseudo-queue in the user-code) is true for all platforms (which…
Michael Schnell wrote 9 lines
On 04/24/2013 11:21 AM, Michael Van Canneyt wrote: > > Somewhere the main program loop must call checksynchronize, that is all. > If that (i.e. doing a pseudo-queue in the user-code) is true for all platforms (which would mean that an EventQueue does exist and just is not polled automatically), I don't see why QueueAsyncCall() can't be handled in the same way.

Please note that if you use TThread.Queue or TThread.Synchronize from within the main thread then your code won't be queued, but executed immediately. It is only designed for enqueing code execution for threads that are not the main thread.

Regards,
Sven

Reply by email

Michael Schnell
to Michael Van Canneyt: Because it resides in the LCL and is inherently bound to a GUI. (horrible nogui widgetset…
Michael Van Canneyt wrote
Because it resides in the LCL and is inherently bound to a GUI. (horrible nogui widgetset tricks notwithstanding)

I definitely do not understand why QueuAsnycCall() uses another paradigm than TThread.Queue() that is supposed to provide exactly the same action.

I gather that this is due to historical reasons and do hope that this might be improved some day. E.g. by extracting the basics of the support for thread-to-main thread signaling in a Widget-Type independent unit (supposedly using WidgetType depending include files) from the WidgetType specific units and thus opening a more easy way to provide this service in new Widget-Types.

-Michael

Reply by email

Michael Schnell
to Sven Barth: Please note that if you use TThread.Queue or TThread.Synchronize from within the main…
Sven Barth wrote 5 lines
Please note that if you use TThread.Queue or TThread.Synchronize from within the main thread then your code won't be queued, but executed immediately. It is only designed for enqueing code execution for threads that are not the main thread.

I see the difference but I don't see a general advantage or disadvantage of this. QueueAsnyCall might or might not do the same.

-Michael

Reply by email

Sven Barth
to Michael Schnell: Thus I would assume that CheckSynchronize also checks the QueueAsncCall() results. If not…
Michael Schnell wrote 11 lines
On 04/24/2013 11:19 AM, Sven Barth wrote: > Both TThread.Queue and TThread.Synchronize just need calls to > CheckSynchronize to be processed. Which is normally done by the > widgetset event loop, but can be done manually as well (I'm using > this for example in a highly threaded console application; the main > thread there just calls CheckSynchronize while the rest is done in > threads). > Thus I would assume that CheckSynchronize also checks the QueueAsncCall() results. If not I would consider this a design glitch (which supposedly easily could be corrected).

No, it does not. QueueAsyncCall is implemented/provided by the LCL not the RTL.

Regards,
Sven

Reply by email

Michael Schnell
Sven Barth wrote
QueueAsyncCall is implemented/provided by the LCL not the RTL.

OK. I understand. But this in fact is a very bad idea.

-Michael

Reply by email

Sven Barth
to Michael Schnell
Michael Schnell wrote 5 lines
On 04/24/2013 11:34 AM, Sven Barth wrote: > QueueAsyncCall is implemented/provided by the LCL not the RTL. > OK. I understand. But this in fact is a very bad idea.

QueueAsyncCall was implemented before TThread.Queue, because the Lazarus developers thought it is a good idea (which I basically agree to)...

Regards,
Sven

Reply by email

Sven Barth
to Michael Schnell: I see the difference but I don't see a general advantage or disadvantage of this.…
Michael Schnell wrote 9 lines
On 04/24/2013 11:32 AM, Sven Barth wrote: > Please note that if you use TThread.Queue or TThread.Synchronize from > within the main thread then your code won't be queued, but executed > immediately. It is only designed for enqueing code execution for > threads that are not the main thread. > I see the difference but I don't see a general advantage or disadvantage of this. QueueAsnyCall might or might not do the same.

QueueAsyncCall can't do anything different, because it needs to go through either TThread.Queue or TThread.Synchronize as the queue's implementation is not directly accessible from the outside and I don't intend to change this.

Regards,
Sven

Reply by email

Michael Schnell
to Sven Barth: QueueAsyncCall was implemented before TThread.Queue, because the Lazarus developers…
Sven Barth wrote 5 lines
QueueAsyncCall was implemented before TThread.Queue, because the Lazarus developers thought it is a good idea (which I basically agree to)...

Yep.

But now it would be a good idea to overcome this situation - that obviously is introduced by two different teams doing the LCL and the RTL and designs - by a unified solution, that handles the thread-to-mainthread signaling in a single WidgetType-independent (set of) unit(s) (supposedly residing in the RTL), that provides an interface that can used by any WidgetType in the LCL and is versatile enough to allow for WidgetTypes that need to adhere to an external GUI-provided event Queue (such as Windows) and a parallel internal non-GUI-EventQueue (such as KDE).

Based on this the "CustomDrawn" and "fpGUI" WidgetTypes can easily provide this full functionality, and a non-horrible "active NoGUI" WidgetType can be done.

-Michael

Reply by email

Michael Van Canneyt
to Michael Schnell
Michael Schnell wrote 19 lines
On 04/24/2013 11:48 AM, Sven Barth wrote: > > QueueAsyncCall was implemented before TThread.Queue, because the Lazarus > developers thought it is a good idea (which I basically agree to)... > Yep. But now it would be a good idea to overcome this situation - that obviously is introduced by two different teams doing the LCL and the RTL and designs - by a unified solution, that handles the thread-to-mainthread signaling in a single WidgetType-independent (set of) unit(s) (supposedly residing in the RTL), that provides an interface that can used by any WidgetType in the LCL and is versatile enough to allow for WidgetTypes that need to adhere to an external GUI-provided event Queue (such as Windows) and a parallel internal non-GUI-EventQueue (such as KDE). Based on this the "CustomDrawn" and "fpGUI" WidgetTypes can easily provide this full functionality, and a non-horrible "active NoGUI" WidgetType can be done.

What are you waiting for ?

All you need to do is implement an event loop. All the rest is there.

Michael.

Reply by email

Michael Schnell
to Michael Van Canneyt
Michael Van Canneyt wrote 6 lines
? What are you waiting for ? All you need to do is implement an event loop. All the rest is there.

As I said, I already did try this some years ago Trying both to implement a new event queue mechanism (stolen from mse), and - better idea - reusing the event queue code from the "GTK" WidgetType. But I gave up after some weeks (not fulltime, of course) due to the enormous complexity of the Lazarus units involved.

In fact I did only take a look at the Lazarus units, not the RTL, at that time not knowing that it would need to be revised, too.

A major political problem is that - to do it right - all WidgetType units that are dealing with the EventQueue would need to be modified (e. g. using the new RTL interface and moving QueueAsncCall out), and of course the basic work needs to be done in the RTL (e. g providing the "SignalMainThread" interface with an EventQueue that is to be used for non-GUI events (and be merged with the GUI events from the LCL at the queue input (GTK and many others) or the queue output (Windows) and moving QueueAsncCall in).

This would need a huge testing effort to guarantee that existing code would not be broken.

All this can't be done by a one-man team of volunteers.

As always, I feel that before trying any start on this, a rather commonly agreed concept would need to be decided upon.

-Michael

Reply by email

Michael Van Canneyt
to Michael Schnell
Michael Schnell wrote 28 lines
On 04/24/2013 12:34 PM, Michael Van Canneyt wrote: > ? > What are you waiting for ? > > All you need to do is implement an event loop. All the rest is there. > > As I said, I already did try this some years ago Trying both to implement a new event queue mechanism (stolen from mse), and - better idea - reusing the event queue code from the "GTK" WidgetType. But I gave up after some weeks (not fulltime, of course) due to the enormous complexity of the Lazarus units involved. In fact I did only take a look at the Lazarus units, not the RTL, at that time not knowing that it would need to be revised, too. A major political problem is that - to do it right - all WidgetType units that are dealing with the EventQueue would need to be modified (e. g. using the new RTL interface and moving QueueAsncCall out), and of course the basic work needs to be done in the RTL (e. g providing the "SignalMainThread" interface with an EventQueue that is to be used for non-GUI events (and be merged with the GUI events from the LCL at the queue input (GTK and many others) or the queue output (Windows) and moving QueueAsncCall in). This would need a huge testing effort to guarantee that existing code would not be broken. All this can't be done by a one-man team of volunteers.

Of course it can.

You make the task far too complex. Start by NOT looking at the LCL code.

You need simply to start with

TCustomEventLoopApplication = Class(TCustomApplication)
// Whatever
end;

Which abstracts the event loop.

Then you implement a

TConsoleEventLoopApplication = class(TCustomEventLoopApplication)
// Whatever
end;

which implements the event loop for console apps using whatever mechanism you see fit. You could e.g. make use of libevent which provides a ready-to-go event loop.

This will demonstrate that your concept works.

After that, the remaining task is to make sure that TApplication from the LCL can be built on top of TCustomEventLoopApplication. I'm sure this will not take too long.

All this is perfectly doable for 1 person.

Michael.

Reply by email

Marco van de Voort
to Michael Van Canneyt
Michael Van Canneyt wrote 29 lines
Of course it can. You make the task far too complex. Start by NOT looking at the LCL code. You need simply to start with TCustomEventLoopApplication = Class(TCustomApplication) // Whatever end; Which abstracts the event loop. Then you implement a TConsoleEventLoopApplication = class(TCustomEventLoopApplication) // Whatever end; which implements the event loop for console apps using whatever mechanism you see fit. You could e.g. make use of libevent which provides a ready-to-go event loop. This will demonstrate that your concept works. After that, the remaining task is to make sure that TApplication from the LCL can be built on top of TCustomEventLoopApplication. I'm sure this will not take too long. All this is perfectly doable for 1 person.

The base win32 pattern can be seen in (the old) ICS v5 (overbyte.be), unit conio.

IIRC it uses (under Delphi) forms.allocatehwnd which is annoying since it is a non visual component in a visual unit. It did contain some primitives for D1 though, which I used in the FPC port.

Reply by email

Michael Schnell
to Sven Barth: QueueAsyncCall can't do anything different, because it needs to go through either…
Sven Barth wrote 6 lines
QueueAsyncCall can't do anything different, because it needs to go through either TThread.Queue or TThread.Synchronize as the queue's implementation is not directly accessible from the outside and I don't intend to change this.

It can't be true that it goes through TThread.Synchronize (if not using a hidden parameter as done in Delphi), as this would trash the functionality.

It does not seem to go through TThread.Queue as (1) in Lazarus/FPC it is older than TThread.Queue and (2) in this Forum thread it has been claimed that QueueAsyncCall does not work by means of checksynchronize, while TThread.Queue does-.

-Michael

Reply by email

Hans-Peter Diettrich
to Michael Van Canneyt: Because it resides in the LCL and is inherently bound to a GUI. (horrible nogui widgetset…
Show quoted text 18 lines
On Wed, 24 Apr 2013, Michael Schnell wrote: > On 04/24/2013 11:21 AM, Michael Van Canneyt wrote: >> >> Somewhere the main program loop must call checksynchronize, that is all. >> > > If that (i.e. doing a pseudo-queue in the user-code) is true for all > platforms (which would mean that an EventQueue does exist and just is > not polled automatically), I don't see why QueueAsyncCall() can't be > handled in the same way. Because it resides in the LCL and is inherently bound to a GUI. (horrible nogui widgetset tricks notwithstanding) The RTL does not need a GUI.

Even non-GUI programs may need event/message handling, like (Windows) services, or servers in a client-server scenario. But AFAIK according inter-process communication is very platform specific, dunno what common means the RTL offers for such purposes.

Dodi

Reply by email

Sven Barth
to Michael Schnell: It can't be true that it goes through TThread.Synchronize (if not using a hidden…
Michael Schnell wrote 15 lines
On 04/24/2013 11:52 AM, Sven Barth wrote: > > QueueAsyncCall can't do anything different, because it needs to go > through either TThread.Queue or TThread.Synchronize as the queue's > implementation is not directly accessible from the outside and I don't > intend to change this. > It can't be true that it goes through TThread.Synchronize (if not using a hidden parameter as done in Delphi), as this would trash the functionality. It does not seem to go through TThread.Queue as (1) in Lazarus/FPC it is older than TThread.Queue and (2) in this Forum thread it has been claimed that QueueAsyncCall does not work by means of checksynchronize, while TThread.Queue does-.

You misunderstood me (and maybe my answer wasn't clear enough to be understood correctly). You said that "QueueAsyncCall might or might not do the same". I thought that you mean a future implementation of QueueAsyncCall which should use the same queue mechanism that TThread.Queue and TThread.Synchronize use (both use the same). And in that case this won't work, because the queueing mechanism is only available in the Classes unit and if it uses TThread.Queue (let's put aside TThread.Synchronize) then there is the problem that the mainthread can not queue anything, because that will be executed immediately.

Regards,
Sven

Reply by email

Michael Schnell
to Hans-Peter Diettrich: Even non-GUI programs may need event/message handling, like (Windows) services, or…
Hans-Peter Diettrich wrote
But AFAIK according inter-process communication is very platform specific, dunno what common means the RTL offers for such purposes.

Obviously, the RTL alone can't do it. The dirty details of the EventQueue handling needs to be done in the LCL (or at least with the LCL in mind), because you need to merge the GUI-events with the internal "language" events. ( I understand that with Windows the merging needs to take place at the "output" of the EventQueue(s), while with other WidgetTypes the merging needs to take place at the "input" of the EventQueue(s). )

This is why I claim, that a decent solution needs to introduce modifications in the RTL and in all LCL WidgetType implementations (that provide GUI-events). (You can take a look at the mse-project that seems to have a kind of unified RTL and LCL. here the EventQueues already works perfectly on all supported platforms with and without a GUI binding.

I feel that the code for the "Language" event queue needs to be done in the RTL (I suppose it already is, because you can use it via checksynchronize() ). The LCL WidgetType code thus should not create yet another Queue (as it is done right now), but the RTL should enable it to merge events GUI form an external Queue (such as existing in Windows) or push GUI events in the RTL Queue (supposedly viable for GTK and other Widgets)

On top of this decent "full featured" non-GUI WidgetTypes (for "embedded" main programs, CGI-programs, Daemons, Windows services, ...), and new WidgetTypes (e.g. Browser handled: similar to ExtPascel, ...) can much easier be done.

I suppose this is the main problem: for a decent solution a common concept for RTL and LCL (i.e. a decent interface-definition based on objects) needs to be defined and agreed upon by both core teams, before any work can be started. (I fear this never will happen.)

-Michael

Reply by email

Michael Schnell
to Sven Barth: You misunderstood me (and maybe my answer wasn't clear enough to be understood…
Sven Barth wrote
I thought that you mean a future implementation of QueueAsyncCall

Sorry for being not clear. I meant that I just don't know whether the current implementation of QueueAsyncCall, if called from the main thread, will do a call or will push an event to the Queue, and that I don't think that is of great signification (in case either does work).

-Michael

Reply by email