Home > Software engineering >  RestClient and thread locking
RestClient and thread locking

Time:02-28

Using Delphi 10.4

Using the tool REST Debugger, called an API, And got compoents.

Calling the Componets with

begin
  writeln('starting');
    RESTRequest1.Execute; writeln('finieshed 1');
    RESTRequest2.Execute; writeln('finieshed 2');
    RESTRequest3.Execute; writeln('finieshed 3');
  writeln('Done.');

end;

when i debug the code

and in the Execute there is a line

  // Eventhandlers AFTER Observers
  HandleEvent(DoAfterExecute);

which leads to the procedure:

class procedure TThread.Synchronize(const AThread: TThread; AMethod: TThreadMethod);
var
  LSynchronize: TSynchronizeRecord;
begin
  LSynchronize.Init(AThread, AMethod);
  Synchronize(@LSynchronize); // <--- here
end;

and the code locks.

I think its a dead lock, however I don't know what is locked.

the setup is a Thread in console application.

Download := TDownload.Create(nil);
// Simulate service start.
Download.ServiceStart(Download, MyDummyBoolean);
readln;
// On exit, destroy the service object.
FreeAndNil(DownloadInvoices);

The Documentation of RestClient is lacking. What it is locked? or How to identify the locking procedure?

CodePudding user response:

Your problem is with the Synchronize call in the RTL.

Synchronize is picked up in the main message loop when the application is idle (i.e. it has no events to process).

As you have said this is a console application I suspect you do not have a main message loop that can register that the application is idle, or process the waiting Synchronize calls.

There's no way around that if you want to use components that call Syncronize - you must have an appropriate message loop. The easiest way is to implement a simple VCL, FMX or Service application and the Synchronize calls will succeed.

As an alternative you can write your own main loop. As per Remy Lebeau's comments below you need to call CheckSynchronize() periodically, and you can make use of the RTL's SyncEvent to know when to call CheckSynchronize(). The documentation also mentions using the global variable WakeMainThread to store an object method (TNotifyEvent) that is called when the worker thread has obtained the lock on the main thread.

The edit is not allowing me to add links for some reason. For CheckSynchronize see: https://docwiki.embarcadero.com/Libraries/en/System.Classes.CheckSynchronize

For SyncEvent see: https://docwiki.embarcadero.com/Libraries/en/System.Classes.SyncEvent

  • Related