Reputation: 323
I currently have stable code between a client (IdTCPClient) and a server (IdTCPServer) working all as planned. When I call the following function from an OnClick event of a button, however, the server freezes.
var
SendStream: TMemoryStream;
FileStream: TFileStream;
List: TList;
I: Integer;
begin
try
//Load
FileStream := TFileStream.Create(Path, fmOpenRead);
FileStream.Position := 0;
//Place into stream
SendStream := TMemoryStream.Create;
SendStream.Write(Header, SizeOf(Header)); //This works; supporting code ommitted for brevity
SendStream.CopyFrom(FileStream, FileStream.Size);
SendStream.Position := 0;
TIdContext(fTCP.Contexts.LockList[0]).Connection.IOHandler.Write(SendStream, 0, True);
fTCp.Contexts.LockList;
if Assigned(Self.fServerOnSync) then Self.fServerOnSync(SizeOf(Header)) //event handler for main form
finally
FileStream.Free;
SendStream.Free;
end;
I am guessing it has something to do with deadlocking threads but for the life of me I have no idea why it's occuring.
Also, if I encapsulate the above code in some class that contains the IdTCP server, which will call my custom fServerOnSync event, is this threadsafe?
Cheers, Adrian
Upvotes: 1
Views: 1130
Reputation: 596287
You are calling fTCp.Contexts.LockList()
twice, but you are not calling fTCp.Contexts.UnlockList()
at all, so the server will become deadlocked whenever it tries to access the Contexts
list. You need to unlock the list after you have locked it, eg:
var
SendStream: TMemoryStream;
FileStream: TFileStream;
List: TList;
I: Integer;
begin
FileStream := TFileStream.Create(Path, fmOpenRead or fmShareDenyWrite);
try
SendStream := TMemoryStream.Create;
try
SendStream.Write(Header, SizeOf(Header));
SendStream.CopyFrom(FileStream, FileStream.Size);
SendStream.Position := 0;
List := fTCP.Contexts.LockList;
try
TIdContext(List[0]).Connection.IOHandler.Write(SendStream, 0, True);
finally
fTCP.Contexts.UnlockList;
end;
if Assigned(fServerOnSync) then fServerOnSync(SizeOf(Header));
finally
SendStream.Free;
end;
finally
FileStream.Free;
end;
...
end;
Upvotes: 1