procedure TIdTCPServer.SetActive(AValue: Boolean);
var
i: Integer;
LListenerThread: TIdListenerThread;
begin
// SG 28/11/01: removed the "try..finally FActive := AValue; end;" wrapper
// SG 28/11/01: It cause the component to be locked in the "active" state, even if
// SG 28/11/01: the socket couldn't be bound.
if (not (csDesigning in ComponentState)) and (FActive <> AValue)
and (not (csLoading in ComponentState)) then begin
if AValue then begin
// InitializeCommandHandlers must be called only at runtime, and only after streaming
// has occured. This used to be in .Loaded and that worked for forms. It failed
// for dynamically created instances and also for descendant classes.
if not FCommandHandlersInitialized then begin
FCommandHandlersInitialized := True;
InitializeCommandHandlers;
end;
// Set up bindings
if Bindings.Count = 0 then begin
Bindings.Add;
end;
// Set up ThreadMgr
ThreadMgr.ThreadClass := ThreadClass;
// Setup IOHandler
if not Assigned(FIOHandler) then begin
IOHandler := TIdServerIOHandlerSocket.Create(self);
FImplicitIOHandler := true;
end;
// Update reply texts for "global" replies
ReplyTexts.UpdateText(ReplyUnknownCommand);
ReplyTexts.UpdateText(MaxConnectionReply);
// Set up listener threads
IOHandler.Init;
i := 0;
try
while i < Bindings.Count do begin
with Bindings[i] do begin
AllocateSocket;
if (FReuseSocket = rsTrue) or ((FReuseSocket = rsOSDependent) and (GOSType = otLinux))
then begin
SetSockOpt(Id_SOL_SOCKET, Id_SO_REUSEADDR, PChar(@Id_SO_True), SizeOf(Id_SO_True));
end;
Bind;
end;
Inc(i);
end;
except
Dec(i); // the one that failed doesn't need to be closed
while i >= 0 do begin
Bindings[i].CloseSocket;
Dec(i);
end;
FActive := True;
SetActive(False); // allow descendants to clean up
raise;
end;
FListenerThreads := TThreadList.Create;
for i := 0 to Bindings.Count - 1 do begin
Bindings[i].Listen(FListenQueue);
LListenerThread := TIdListenerThread.Create(Self, Bindings[i]);
FListenerThreads.Add(LListenerThread);
LListenerThread.Start;
end;
FActive := True; // fixed by Liu Yang 2004.7.24
end else begin
TerminateListenerThreads;
FActive := false; // fixed by Liu Yang 2004.7.24
// Tear down ThreadMgr
try
TerminateAllThreads;
finally
if ImplicitThreadMgr and TIdThreadSafeList(Threads).IsCountLessThan(1) then begin // DONE -oAPR: BUG! Threads still live, Mgr dead ;-(
FreeAndNil(FThreadMgr);
FImplicitThreadMgr := False;
end;
end;//tryf
end;
end;
FActive := AValue;
end;