Sign in Join

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

Mailing lists / lazarus / 2015-10

How does one add an event to a blocking system?

15 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

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

Bo Berglund

I need a TCP port component that can work as a non-blocking port for receiving data. THe data arrival should trigger an event where I can read the data.
So if I use a thread to read data from the socket, how do I signal to the main application that data are arriving using an event? Is there some resource available as a guide?

Bo Berglund Developer in Sweden

Reply by email

Michael Schnell
to Bo Berglund
Bo Berglund wrote
So if I use a thread to read data from the socket, how do I signal to the main application that data are arriving using an event?

TThread.Synchronize(), TThread.Queue()

In an "Application" (other than in a "Program" you also can use "Application.QueueAsyncCall()".

You supposedly want to transfer Data to the main thread. Here IMHO it's a nice idea to use Finalizers.

-Michael

Reply by email

leledumbo
to Bo Berglund: I need a TCP port component that can work as a non-blocking port for receiving data. THe…
So if I use a thread to read data from the socket, how do I signal to

the main application that data are arriving using an event?

Exactly, using an event:
http://www.freepascal.org/docs-html/fcl/syncobjs/tevent.html Here's an example of how to use:
RoundRobinExample.zip
<http://free-pascal-lazarus.989080.n3.nabble.com/file/n4044829/RoundRobinExample.zip>

Reply by email

Mark Morgan Lloyd
to Michael Schnell: TThread.Synchronize(), TThread.Queue() In an "Application" (other than in a "Program" you…
Michael Schnell wrote
On 10/21/2015 01:44 PM, Bo Berglund wrote: > So if I use a thread to read data from the socket, how do I signal to > the main application that data are arriving using an event? TThread.Synchronize(), TThread.Queue()

Please remind us what a non-LCL program has to call to make sure that stuff is dequeued.

Show quoted text 5 lines
In an "Application" (other than in a "Program" you also can use "Application.QueueAsyncCall()". You supposedly want to transfer Data to the main thread. Here IMHO it's a nice idea to use Finalizers.
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

Michael Schnell
to Michael Schnell
Michael Schnell wrote
CheckSynchronize()

Unfortunately there is no decent documentation on CheckSynchronize().

So in very short (and just hopefully correct):

CheckSynchronize() needs to be called by the main thread (in fact a threat becomes the main thread _because_ it calls CheckSynchronize().

The Events thrown by other Threads via TThread.Synchronize and TThread.Queue are executed as sub-procedures of CheckSynchronize() and hence they are executed in the main thread and they are executed in the order they have been queued by other threads.

It is a very bad idea to do a closed loop such as

while (TRUE) CheckSynchronize();

As this will use 100 % CPU time and hence will reduce the performance of all other threads (and every application that is running on the processor).

That is why CheckSynchronize() provides using the parameter "Timeout", that defines how long to wait until returning in case no event is queued. (0 or no parameter => return immediately)

AFAIR if an Event is in the queue same is executed and CheckSynchronize(I) returns without checking if more Events are queued.

AFAIK the return parameter of CheckSynchronize() does not give any decent result and needs to be ignored.

-Michael

Reply by email

Mark Morgan Lloyd
to Michael Schnell: CheckSynchronize() -Michael
Michael Schnell wrote 7 lines
On 10/21/2015 02:39 PM, Mark Morgan Lloyd wrote: > TThread.Synchronize(), TThread.Queue() > > Please remind us what a non-LCL program has to call to make sure that > stuff is dequeued. CheckSynchronize()

Thanks, it's one of those things I can never remember.

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

Mark Morgan Lloyd
to Michael Schnell: Unfortunately there is no decent documentation on CheckSynchronize(). So in very short…
Michael Schnell wrote 31 lines
On 10/21/2015 02:42 PM, Michael Schnell wrote: > CheckSynchronize() > Unfortunately there is no decent documentation on CheckSynchronize(). So in very short (and just hopefully correct): CheckSynchronize() needs to be called by the main thread (in fact a threat becomes the main thread _because_ it calls CheckSynchronize(). The Events thrown by other Threads via TThread.Synchronize and TThread.Queue are executed as sub-procedures of CheckSynchronize() and hence they are executed in the main thread and they are executed in the order they have been queued by other threads. It is a very bad idea to do a closed loop such as while (TRUE) CheckSynchronize(); As this will use 100 % CPU time and hence will reduce the performance of all other threads (and every application that is running on the processor). That is why CheckSynchronize() provides using the parameter "Timeout", that defines how long to wait until returning in case no event is queued. (0 or no parameter => return immediately) AFAIR if an Event is in the queue same is executed and CheckSynchronize(I) returns without checking if more Events are queued. AFAIK the return parameter of CheckSynchronize() does not give any decent result and needs to be ignored.

Seems reasonable. I think I've used it in one place, which is a console program which spends most of its time waiting for keyboard input but also has

procedure MainThreadYield;
begin
   Assert(InterlockedExchange(mainThreadYieldEntryCounter, 1) = 0,
'MainThreadYield reentered');
{$ifndef LCL }
   CheckSynchronize;
{$endif LCL  }
   Assert(InterlockedExchange(mainThreadYieldEntryCounter, 0) = 1,
'MainThreadYield reexited')
end { MainThreadYield } ;

I don't know whether I've overlooked anything significant there, but it appears robust and activity triggered by around half a dozen background threads appears as expected.

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

Michael Schnell
to Mark Morgan Lloyd
Mark Morgan Lloyd wrote 5 lines
I don't know whether I've overlooked anything significant there, but it appears robust and activity triggered by around half a dozen background threads appears as expected.

Of course it's robust.

But check the CPU usage. It it's 100% all threads get just time slices- If it's just one other thread, same will never get more than 50 %.

If it's not 100% the system is waiting somewhere else in a sleep, a blocking read or similar.

-Michael

Reply by email

Sven Barth
to Michael Schnell: Unfortunately there is no decent documentation on CheckSynchronize(). So in very short…
"Michael Schnell" wrote
CheckSynchronize() needs to be called by the main thread (in fact a

threat becomes the main thread _because_ it calls CheckSynchronize().

The part in parenthesis is wrong. CheckSynchronize checks for MainThreadID which is determined independently of CheckSynchronize.

The Events thrown by other Threads via TThread.Synchronize and

TThread.Queue are executed as sub-procedures of CheckSynchronize() and hence they are executed in the main thread and they are executed in the order they have been queued by other threads.

Better usage of terms: Exceptions are thrown (or raised), events are signaled.

AFAIR if an Event is in the queue same is executed and

CheckSynchronize(I) returns without checking if more Events are queued.

CheckSynchronize completely cwalks the lost before it returns.

AFAIK the return parameter of CheckSynchronize() does not give any decent

result and needs to be ignored.

That is indeed always "false" right now. I should check sometime what it is supposed to return... Probably whether at least one event got executed :/

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20151021/2046dba6/attachment.html>

Reply by email

Mark Morgan Lloyd
to Michael Schnell: Of course it's robust. But check the CPU usage. It it's 100% all threads get just time…
Michael Schnell wrote 7 lines
On 10/21/2015 04:19 PM, Mark Morgan Lloyd wrote: > > I don't know whether I've overlooked anything significant there, but > it appears robust and activity triggered by around half a dozen > background threads appears as expected. Of course it's robust.

But my use of it might not have been.

Show quoted text 5 lines
But check the CPU usage. It it's 100% all threads get just time slices- If it's just one other thread, same will never get more than 50 %. If it's not 100% the system is waiting somewhere else in a sleep, a blocking read or similar.

CPU usage depends on what the hardware I'm emulating is doing :-)

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

Michael Schnell
to Sven Barth: threat becomes the main thread _because_ it calls CheckSynchronize(). The part in…
Sven Barth wrote
CheckSynchronize checks for MainThreadID which is determined independently of CheckSynchronize.

I see. I suppose the would-be MainThread is just the thread that is used to start the application. That does make sense. For the internal logic of the Lazarus application the fact that it calls CheckSynchronize() is what makes the difference.

Better usage of terms: Exceptions are thrown (or raised), events are signaled.

You are right. "thrown" is not a good wording for Events. I mostly read "fired" on that behalf.

CheckSynchronize completely walks the lost before it returns.

Thanks a lot for the correction. This is very important to me (see below).

Show quoted text 7 lines
> AFAIK the return parameter of CheckSynchronize() does not give any decent result and needs to be ignored. That is indeed always "false" right now. I should check sometime what it is supposed to return... Probably whether at least one event got executed :/

Maybe the original idea was to have CheckSynchronize execute only one Event and return TRUE if more events up are to be handled.

With this (not existing) design, I would need to do something like:

procedure TmyApplication.ProcessMessages;
begin
while CheckSynchronize() do (*nothing*) ;
end;

With the current design just

procedure TmyApplication.ProcessMessages;
begin
CheckSynchronize();
end;

would be OK, but the code above would work, as well and maybe should be preferred for possible future extension.

-Michael

Reply by email

Mark Morgan Lloyd
to Michael Schnell
Michael Schnell wrote 6 lines
On 10/21/2015 05:27 PM, Sven Barth wrote: > Better usage of terms: Exceptions are thrown (or raised), events are > signaled. You are right. "thrown" is not a good wording for Events. I mostly read "fired" on that behalf.

"Signalled" is not a good choice IMO, because of unix-style signals and their handlers (e.g. sending a HUP signal to a process, to get it to re-read its configuration).

"Triggered" can have problems if a database is being used.

"Fired" seems like a fairly good choice, since it also implies immediacy.

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

Sven Barth
to Mark Morgan Lloyd

Am 22.10.2015 10:21 schrieb "Mark Morgan Lloyd" <

Show quoted text 8 lines
: Michael Schnell wrote: > On 10/21/2015 05:27 PM, Sven Barth wrote: >> Better usage of terms: Exceptions are thrown (or raised), events are

signaled.

> > You are right. "thrown" is not a good wording for Events. I mostly read

"fired" on that behalf.

"Signalled" is not a good choice IMO, because of unix-style signals and

their handlers (e.g. sending a HUP signal to a process, to get it to re-read its configuration).

"Triggered" can have problems if a database is being used. "Fired" seems like a fairly good choice, since it also implies immediacy.

Yes, there is a bit of ambiguity with "signaled" and "fired" indeed seems best :)

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20151022/4f4ea5fe/attachment.html>

Reply by email