Форум: "Сети";
Текущий архив: 2011.04.24;
Скачать: [xml.tar.bz2];
ВнизЗависание IdHTTPProxyServer Найти похожие ветки
← →
kernel © (2009-03-09 08:39) [0]Доброго времени суток, уважаемые!
Использую последнюю версию Инди. При попытке остановить сабжевый сервер программа (VCL) виснет (хотя сам прокси вроде бы останавливается). Попытки остановить его установкой Active в false не успешны. Также пробовал отсоединять каждого юзера из LockList - не помогает (работает через раз). Может быть, сам прокси не правильно создаю (хотя вроде ничего сложного тут нет)?mtProxy:=TIdHTTPProxyServer.Create;
with mtProxy do begin
DefaultPort:=Port;
Bindings.DefaultPort:=Port;
DefaultTransferMode:=tmStreaming;
Active:=true;
end;
Я что-то пропустил? В чем может быть проблема?
Заранее благодарю каждого ответившего.
← →
kernel © (2009-03-09 21:23) [1]Добрался до IdScheduler: виснет на цикле процедуры TerminateAllYarns. Может быть нужно IdHTTPProxyServer.Scheduler какой-то указать?
← →
Сергей М. © (2009-03-10 09:03) [2]
> виснет на цикле процедуры TerminateAllYarns
Что ж дальше не пошел ?
В теле TerminateAllYarns для каждого треда, созданного сервером, вызывается метод:procedure TIdSchedulerOfThread.TerminateYarn(AYarn: TIdYarn);
var
LYarn: TIdYarnOfThread;
begin
Assert(AYarn<>nil);
LYarn := TIdYarnOfThread(AYarn);
if LYarn.Thread = nil then begin
FreeAndNil(LYarn);
end
else if LYarn.Thread.Suspended then begin
// If suspended, was created but never started
// ie waiting on connection accept
FreeAndNil(LYarn.FThread);
end else
begin
// Is already running and will free itself
LYarn.Thread.Stop; // <-- смотрим реализацию метода Stop
// Dont free the yarn. The thread frees it (IdThread.pas)
end;
end;procedure TIdThread.Stop;
begin
FLock.Enter; try
if not Stopped then begin
case FStopMode of
smTerminate: Terminate; // <-- все что делает метод Stop - это взводит у объекта-треда флаг Terminated !!!!!!
smSuspend: {DO not suspend here. Suspend is immediate. See Execute for implementation};
end;
Include(FOptions, itoStopped);
end;
finally FLock.Leave; end;
end;
Отсюда вывод - треды сервера д.б. реализованы таким образом, чтобы как можно чаще осуществлялся опрос флага Terminated с целью обнаружения "команды закругляться по хозяйству".
← →
kernel © (2009-03-10 14:42) [3]Так в тредах же и так проверяется флаг Terminated на каждом шагу?!
...
while not Terminated do begin
if Stopped then begin
DoStopped;
// It is possible that either in the DoStopped or from another thread,
// the thread is restarted, in which case we dont want to restop it.
if Stopped then begin // DONE: if terminated?
if Terminated then begin
Break;
end;
Suspend; // Thread manager will revive us
if Terminated then begin
Break;
end;
end;
end;
Include(FOptions, itoReqCleanup);
try
try
BeforeRun;
try
if Loop then begin
while not Stopped do begin
try
Run;
except
on E: Exception do begin
if not HandleRunException(E) then begin
Terminate;
raise;
end;
...
Или я что-то не понимаю?
← →
Сергей М. © (2009-03-10 15:19) [4]
> if Loop then begin
> while not Stopped do begin
> try
> Run; // <-- здесь происходит вызов польз.обработчиков событий. в которых ты волен наплевав на всякие проверки "зависнуть" в блокирующем ожидании чего-либо
> except
← →
kernel © (2009-03-10 16:33) [5]Что-то не могу я понять, куда ведет Run (т.е. где этот Run искать)? Или от него сразу идет переход на CommandPassThrough?
← →
Сергей М. © (2009-03-10 16:50) [6]
> где этот Run искать
Ищи там где он объявлен как override
← →
kernel © (2009-03-10 18:18) [7]Но Run же срабатывает только когда к серверу приходит запрос от клиента? После остановки сервера до Run (и вообще до внутренностей потока) дело не доходит. Он лишь скачет по циклу while True do begin в TerminateAllYarns, а Count в этом же цикле застревает на 1, т.е. в цикле условие
if Count = 0 then begin
Break;
end;
не проходит.
Я пробовал "отрубать" TerminateAllYarns в IdCustomTCPServer, сервер стабильно отключался. Но что-то меня этот метод пугает...
← →
Сергей М. © (2009-03-10 20:24) [8]
> Run же срабатывает только когда к серверу приходит запрос
> от клиента?
Нет, Run вызывается циклически (см. код) до тех пор пока тред, обслуживающий установленное соединение, не перейдет в состояние Stopped.
При этом установившие соединение стороны могут сколь угодно долго "молчать", не проявляя никакой активности.
← →
kernel © (2009-03-15 15:29) [9]Я совсем уже запутался 8[
После зависания обращения к Run не происходит. Т.е. получается IdThread.Execute всегда успешно проходит.
Где копать?
← →
kernel © (2009-03-15 18:37) [10]Все, устал "ремонтировать" проблему. Отключил TerminateAllYarns, все работает отлично. Только треды, наверное, не убиваются...
← →
Сергей М. © (2009-03-15 19:52) [11]
> После зависания обращения к Run не происходит
Вызов Run всегда происходит раньше вызова Execute
← →
kernel © (2009-03-15 20:29) [12]
> Вызов Run всегда происходит раньше вызова Execute
Я обрыл все внутри и Execute, и Run, но так и не нашел, где происходит завис...
PS: Сергей М., спасибо за помощь :)
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2011.04.24;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.004 c