Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Indy synchronize ServerTCPExecute

I'm using TIDTCPServer component. As I understood event ServerTCPExecute(AContext: TIdContext) is not synchronized. What is the best way of synchronising it? I need data to be send to main thread and have them back to format answer.

I'm using Indy 10.5.8.0.

Method 1

Is it something like this I should deal with critical sections to pass data from non synchronized function to application?

var data:string;
.
.
.
procedure MainThreadProcedure;
begin
  ...
end;
.
.
.
procedure IdTCPServerExecute(AContext: TIDContext);
var tmp: string;
begin
.
.
.
EnterCriticalSection(cs);
data:= tmp;
TIdYarnOfThread(AContext.Yarn).Thread.Synchronize(MainThreadProcedure);
LeaveCriticalSection(cs);
end;
like image 804
vico Avatar asked Aug 29 '12 10:08

vico


1 Answers

The correct way is to use Indy's TIdSync class instead of accessing Indy's internal threads directly, eg:

uses
  ..., IdSync;

type
  TMySync = class(TIdSync)
  protected
    procedure DoSynchronize; override;
  public
    data: string; 
  end;

procedure TMySync.DoSynchronize;
begin
  // this runs in the main thread
  // use data as needed...
end;

procedure IdTCPServerExecute(AContext: TIDContext); 
var
  tmp: string;
  sync: TMySync; 
begin 
  tmp := ...;
  sync := TMySync.Create;
  try 
    sync.data := tmp; 
    sync.Synchronize;
  finally
    Sync.Free;
  end; 
end;

Just be careful with any synchronizing you do, whether it be TIdSync or TThread.Synchronize(). If the main thread tries to deactivate the server while the server is trying to sync with the main thread, you will deadlock both the main thread and the server.

like image 140
Remy Lebeau Avatar answered Nov 15 '22 02:11

Remy Lebeau