Newsgroups : Borland : borland.public.delphi.internet.winsock : 2007 Apr : 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