Newsgroups : Borland : borland.public.delphi.internet.winsock : 2007 Apr : Re: Simple Indy Server doesn't receive in order

www.cryer.info
Managed Newsgroup Archive

Re: Simple Indy Server doesn't receive in order

Subject:Re: Simple Indy Server doesn't receive in order
Posted by:"Bo Berglund" (bo.berglu..@telia.com)
Date:Mon, 2 Apr 2007 23:23:49

On Sun, 1 Apr 2007 12:08:25 -0700, "Remy Lebeau \(TeamB\)"
<no.spam@no.spam.com> wrote:

>>    Memo1.Lines.Add( S);
>
>That statement is not thread-safe.  It is being called in the context
>of a worker thread of the server.  You can't safely use VCL UI
>components outside of the main thread.  You must use the TIdSync or
>TIdNotify class (or write your own notification code) to execute that
>statement in the context of the main thread.
>

I have a similar problem where I want to get data from the threads in
the socket interface over to the main thread and vice versa.
I have thought up this mechanism, but will it work correctly:

I have this in the object constructor:
  FCommandResponses := TStringList.Create;
  FCmdListLock := TCriticalSection.Create;

Then I have a few methods to put a string into the list (from one
thread) and to read it out from the list (used by another thread) and
a couple more:


procedure TMachineComm.AddCmdResponse(Msg: string);
{Called from socket comm thread}
begin
  FCmdListLock.Acquire;
  try
    {Remove any linefeeds in the message}
    Msg := StringReplace(Msg, #13, '', [rfReplaceAll]);
    Msg := StringReplace(Msg, #10, '', [rfReplaceAll]);
    {Add to list}
    FCommandResponses.Add(Msg);
  finally
    FCmdListLock.Release;
  end;
end;

function TMachineComm.GetResponseCount: integer;
{Called from main thread}
begin
  FCmdListLock.Acquire;
  try
    Result := FCommandResponses.Count;
  finally
    FCmdListLock.Release;
  end;
end;

function TMachineComm.PeekCmdResponse(Index: integer): string;
{Called from main thread}
begin
  Result := '';
  FCmdListLock.Acquire;
  try
    if (Index < 0) or (Index >= FCommandResponses.Count) then exit;
    Result := FCommandResponses[Index];
  finally
    FCmdListLock.Release;
  end;
end;

function TMachineComm.PopCmdResponse: string;
{Called from main thread}
begin
  Result := '';
  FCmdListLock.Acquire;
  try
    if FCommandResponses.Count = 0 then exit;
    Result := FCommandResponses[0];
    FCommandResponses.Delete(0);
  finally
    FCmdListLock.Release;
  end;
end;

Will this work (i.e. is it thread-safe)???

/Bo

Replies:

In response to:

www.cryer.info
Managed Newsgroup Archive