-
Couldn't load subscription status.
- Fork 172
Description
如当前版本下面的程序在退出时,如果StopLoop是被工作线程调用的。可能出现死锁状态。
`procedure TIocpCrossSocket.StopLoop;
var
I: Integer;
begin
if (FIoThreads = nil) then Exit;
CloseAll;
while (ListensCount > 0) or (ConnectionsCount > 0) do Sleep(1);
for I := 0 to Length(FIoThreads) - 1 do
PostQueuedCompletionStatus(FIocpHandle, 0, 0, POverlapped(SHUTDOWN_FLAG));
CloseHandle(FIocpHandle);
for I := 0 to Length(FIoThreads) - 1 do
begin
FIoThreads[I].WaitFor;
FreeAndNil(FIoThreads[I]);
end;
FIoThreads := nil;
end;
`
建议改为:
`procedure TIocpCrossSocket.StopLoop;
var
I: Integer;
begin
if (FIoThreads = nil) then Exit;
CloseAll;
while (ListensCount > 0) or (ConnectionsCount > 0) do Sleep(1);
for I := 0 to Length(FIoThreads) - 1 do
begin
FIoThreads[I].Terminate;
PostQueuedCompletionStatus(FIocpHandle, 0, 0, POverlapped(SHUTDOWN_FLAG));
end;
for I := 0 to Length(FIoThreads) - 1 do
begin
while not FIoThreads[I].Finished do
begin
if GetCurrentThreadID = MainThreadID then //由于是通过Synchronize同步到主线程执行,所以调用CheckSynchronize,防止死锁
CheckSynchronize(0)
else if GetCurrentThreadID = FIoThreads[I].ThreadID then Break;
Sleep(1);
end;
FreeAndNil(FIoThreads[I]);
end;
CloseHandle(FIocpHandle);
FIoThreads := nil;
end;
`
同理epoll,kqueue