最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Delphi TThreadPool destructor causes a deadlock from DLL built with the runtime packages - Stack Overflow

programmeradmin0浏览0评论

The basic problem lies in the implementation of the RTL library as soon as the ThreadPool destructor collides with the FreeLibrary limitations. TThreadPool.Destroy has a fix to address this issue, note IsDLLDetaching in the code below. Delphi 11 Upd 3

unit System.Threading;

destructor TThreadPool.Destroy;
var
  I: Integer;
  Thread: TBaseWorkerThread;
  LocalFreeList: TList<TBaseWorkerThread>;
begin
  FShutdown := True;
{$IFDEF MSWINDOWS}
  if IsDLLDetaching then
  begin
    if (ThreadPoolMonitorHandles <> nil) and ThreadPoolMonitorHandles.ContainsKey(self) then
    begin
      TerminateThread( ThreadPoolMonitorHandles[self], 0);
      ThreadPoolMonitorHandles.Remove(self);
    end;
    with FThreads.LockList do
    try
      for I := 0 to Count - 1 do
        TerminateThread( Items[I].Handle, 0 );
    finally
      FThreads.UnLockList;
    end;
    FWorkerThreadCount := 0;
  end
  else
{$ENDIF MSWINDOWS}
  begin
    if FQueue <> nil then
    begin
      TMonitor.Enter(FQueue);
      try
        TMonitor.PulseAll(FQueue);
      finally
        TMonitor.Exit(FQueue);
      end;
    end;
    if FThreads <> nil then
    begin
      LocalFreeList := TList<TBaseWorkerThread>.Create;
      try
        with FThreads.LockList do
        try
          // Check each thread to see if it is already marked for termination and/or if it is hung.
          for I := 0 to Count - 1 do
          begin
            Thread := Items[I];
            LocalFreeList.Add(Thread);
          end;
        finally
          FThreads.UnlockList
        end;
        for I := 0 to LocalFreeList.Count - 1 do
          LocalFreeList[I].DisposeOf;
      finally
        LocalFreeList.Free;
      end;
    end;
    Assert(FWorkerThreadCount = 0);
    WaitMonitorThread;
  end;
  FThreads.Free;
  FQueue.Free;
  FQueues.Free;
  FRetiredThreadWakeEvent.Free;
  inherited;
end;

However, doesn't work as expected with the BPL-enabled build. For some reason, the Delphi dev team based the fix on System.IsLibrary flag

发布评论

评论列表(0)

  1. 暂无评论