[Lazarus] lnet sockets, ´"eventer"

Bernd prof7bit at gmail.com
Thu Oct 25 14:03:51 CEST 2012


2012/10/25 Michael Schnell <mschnell at lumino.de>:

> I suppose you mean "...is required by the user to be handled". That means
> that the waiting (here of course not "sleeping", as the "sleeping" is done
> in the LCL) is done in some "magical" way in the guts of the lnet code. This
> does sound nice. Could you explain how it is done and if it is done in a
> _decent_ way (i.e. not performing any polling which would introduce latency
> and CPU cycle overhead) ?

On windows it is handled by existing windows API that fires windows
messages on socket events, the recommended way to do networking on
windows. On other widgetsets I have not yet deeply looked into the
code how it is done but I guess it is using the recommended ways to do
this with the help of the widgetset libs directly there too. The code
for these LCL eventers is separate from the rest of the lnet code, its
not in the lib folder, its in the folder that contains the lazarus
packages.

>> All other eventers (select, epoll, kqueue) are only meant to be used
>> when you explicitly not want the events to be generated by the LCL
>> main thread,
>
> Good for applications that don't use the LCL and (maybe) for using it in
> worker Threads.
>>
>> These eventers always
>> block.
>
> That is what I understand an "eventer" does: It blocks until one of the
> affiliated events is scheduled.

exactly. The select eventer for example is just a thin wrapper around
the unix select() function, the TEventer object maintains a list of
sockets it is responsible for and when you call CallAction() it calls
a blocking select() with this list of sockets and after that returns
it loops through all affected sockets and calls their appropriate
OnXxx methods and then CallAction() returns (and you are supposed to
call it again and again).

>> They have a timeout, so you can make them wake up every x
>> milliseconds but still they block all of the time.
>
> So the events that can be affiliated are generated by the socket in question
> plus a timeout. No more ?

See above, the select is called with this timeout parameter to make it
return after some time even if no evens have happened but only meant
to check some things (maybe the program wants to end) and then you are
supposed to immediately call it again. If select() returns because an
event has happened the eventer goes through all affected sockets in
its list and calls the OnRead, OnWrite or OnError methods and the
socket objects themselves (depending on what type they are or which
state they are in) then call their appropriate OnConnect,
OnDisconnect, OnReceive, OnAccept handlers, all that ultimately
happens from the eventer thread and originates from within this
CallAction() call. In the LCL eventer thee calls originate from the
receiving of a windows message sent from the system.

> What do you mean by "LCL eventers" (in fact I already searched the LCL
> source code and "eventer" is nowhere to be found).

Its part of the Lazarus package in lnet (a separate folder in the lnet
download) there you find code that derives from TEventer base class
and implements all the stuff needed to hooks into the LCL and the
widgetset. These eventers do not have this blocking CallAction()
method because they are supposed to somehow register and react to
windows messages on windows (and some similar magic on other
widgetsets, I am not very familiar with this part of lnet becaue I
have spent most of my time with lnet using it inside a non-gui library
and there I have used the select eventer and one dedicated eventer
thread and my own homegrown message pump to communicate between
threads.




More information about the Lazarus mailing list