[Lazarus] Lazarus and Windows 7

Florian Klaempfl florian at freepascal.org
Sat Aug 15 00:43:08 CEST 2009


Vincent Snijders wrote:
> I have looked a bit more why outputfilter is so slow at parsing a lot 
> of compiler output (e.g. compiling a simple LCL app with -va). The 
> pipe buffer is rather small, NumBytesAvailable is not bigger than 1280 
> bytes. So OnAsyncReadData reads only 1280 bytes at a time. 
> OnAsyncReadData is only called after an application.handlemessage. So 
> on line 319 of outputfilter.pas, the buffer is most times empty, but 
> NumBytesAvailable = 1280, and we are sleeping until 
> Application.HandleMessage is called.
>
> I had some success with the following patch. It does a sleep(0) to 
> give the compiler the chance to write to the pipe again and tries to 
> read it again.
> --- ide/outputfilter.pas
> +++ ide/outputfilter.pas
> @@ -1206,9 +1206,12 @@ var
>    Count: LongWord;
>  begin
>    if fProcess=nil then exit;
> -  Count:=TAsyncProcess(fProcess).NumBytesAvailable;
> -  if Count>0 then
> -    FAsyncOutput.Push(TStream(TAsyncProcess(fProcess).Output),Count);
> +  repeat
> +    Count:=TAsyncProcess(fProcess).NumBytesAvailable;
> +    if Count>0 then
> +      FAsyncOutput.Push(TStream(TAsyncProcess(fProcess).Output),Count);
> +    sleep(0);
> +  until Count=0;
>  end;
>
>  function TOutputFilter.CreateScanners(ScannerOptions: TStrings): 
> boolean;
If I understand it correctly the problem is that TAsyncProcess, 
currently only reads data, when the event is triggered, which is in a 
ProcessMessages. Ouch.

Either TAsyncProcess.OnReadData is transferred into the main loop, in a 
similar way as for the normal TProcess.
I have not tested this, but it should work, as NumBytesAvailable seems 
to be none blocking.
=> This could simplify the overall loop as the handling of the 2 
projects would be more or less the same.

Alternatively, before we sleep(3), we could check for data, and process it.
        end else begin
          // no new input, but process still running
          if TheAsyncProcess.NumBytesAvailable > 0 then
            Application.ProcessMessages
          else
            Sleep(30);
        end;






More information about the Lazarus mailing list