Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it dangerous to use synchronize in a non-VCL application?

If Delphi code was written with synchronize to serialize access to the main VCL thread, but this code then is used in a non-VCL application, will it synchronize with the main thread of the application or just have no effect at all?


Example:

procedure TMyThread.Execute;
begin

  // ... other code

  Synchronize(SomeMethod);

  // ...

end;

Let's assume

  • it is a non-VCL application which has a main thread which executes in an endless loop (or until terminated)
  • the main thread does not call CheckSynchronize directly or in a WakeMainThread handler
  • a secondary thread runs and executes Synchronize(SomeMethod) like in the example above

Will the thread hang on the Synchronize(SomeMethod) line?

like image 475
mjn Avatar asked May 21 '12 16:05

mjn


2 Answers

TThread provides facilities for non-VCL programs to check the synchronization queue, so they can continue to use multithreaded libraries that expect to synchronize their methods. This is described in the documentation for CheckSynchronize. Remember that it's the application's job to check the queue, not your library's.

As long as the application honors its part of the contract, your use of Synchronize should be fine. If it doesn't, though, then your program will not work correctly, but I don't know what exact symptoms to expect. Hanging certainly sounds plausible.

like image 84
Rob Kennedy Avatar answered Sep 21 '22 14:09

Rob Kennedy


Is it dangerous to use synchronize in a non-VCL application?

Yes it is dangerous. If your main thread is not calling CheckSynchronize then Synchronize will result in deadlock.

Let's assume

  • it is a non-VCL application which has a main thread which executes in an endless loop (or until terminated)
  • the main thread does not call CheckSynchronize directly or in a WakeMainThread handler
  • a secondary thread runs and executes Synchronize(SomeMethod) like in the example above

Will the thread hang on the Synchronize(SomeMethod) line?

The call to Synchronize will block the background thread until the main thread calls CheckSynchronize. So, if the main thread never calls CheckSynchronize, the background thread will block indefinitely.

The following program illustrates this:

program TheBigSleep;

{$APPTYPE CONSOLE}

uses
  SysUtils, Classes, Windows;

type
  TMyThread = class(TThread)
  protected
    procedure Execute; override;
  end;

procedure TMyThread.Execute;
begin
  Synchronize(SysUtils.Beep);
end;

begin
  with TMyThread.Create do
    WaitForSingleObject(Handle, INFINITE);
    //don't call WaitFor since that, in turn, calls CheckSynchronize
end.
like image 32
David Heffernan Avatar answered Sep 18 '22 14:09

David Heffernan