[fpc-devel] Strange behaviour with Synapse

Ludo Brands ludo.brands at free.fr
Sun Mar 17 09:05:45 CET 2013


On 03/16/2013 07:55 PM, Ludo Brands wrote:
> On 03/16/2013 07:29 PM, Geoffray Levasseur-Brandin wrote:
>> This is somewhat complex, I know it, but this have been created
>> keeping in mind that I would like to allow parallelization of
>> downloads in the future, as you was supposing it. But I'm agree and
>> if someone have an idea on how simplifying it and almost in a more
>> secure way, allowing parallelization in future I would very
>> appreciate it.
> 
> Instead of re-using TDownloader.FHttp: THTTPSend  for all threads,
> create a THTTPSend per TDownloadDaemon. You have to use multiple
> THTTPSend instances in any case if you want to do parallel downloads.
> Actually, get rid of TDownloader and do everything in TDownloadDaemon.
> Even the HEAD.
> 
Also, get rid of all these synchronizes. When using multiple threads,
you will be blocking your downloads too much. Every sock status change,
you create a string for the GUI, synchronize to update the screen, call
Application.Processmessages to make sure the GUI gets updated. That is a
huge waste of resources and slows down downloads considerably. On top of
that you have timers that also update the GUI.
Turn this around. Have TDownloadDaemon do the complete download and
nothing else. Put status in properties of TDownloadDaemon, using a
critical section if you want to pass strings, and poll your download
threads in the main thread to update the GUI. You have already a timer.
Make it faster (fe. 200ms) and update your GUI from there. Nobody will
see the difference. No more synchronize and Application.Processmessages
anymore and your program flow becomes so much easier. Multi-threading is
difficult and simplifying your program flow is key to getting it right.

I changed the project to GTK2 and got it running. It crashes not always
at the same time but it is systematically in the synchronize in
TDownloadDaemon.SockStatus and always when doing the HEAD. So that is a
synchronize called inside a synchronize from the TDownloadListLoop. You
should not call synchronize from the main loop. Worse,
TDownloadDaemon.SockStatus calls Synchronize(FOnProgress) which calls
TThread.Synchronize(self,AMethod). Self is TDownloadDaemon but since you
call TDownloadDaemon.SockStatus here from the main thread, synchronize
uses the wrong AThread. The first download it happens to work because
there is no thread running when you do HEAD. The second time you aren't
that lucky. In any case, this is an overly complex program flow and is
simply asking for problems.

Ludo





More information about the fpc-devel mailing list