diff options
| author | ondrej <ondrej@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2020-07-03 17:27:17 +0000 |
|---|---|---|
| committer | ondrej <ondrej@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2020-07-03 17:27:17 +0000 |
| commit | 0ace83b6919c53bbd0f4a03522661c00bdcb94d6 (patch) | |
| tree | 407b762d8566b1034f75bac447b3b2c115f1eefe /packages/fcl-web | |
| parent | fd73b1f5d516d5b629bb98779db3f3b424c3769e (diff) | |
| download | fpc-0ace83b6919c53bbd0f4a03522661c00bdcb94d6.tar.gz | |
fphttpserver: gracefully close open connections at server destroy
git-svn-id: https://svn.freepascal.org/svn/fpc/trunk@45723 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'packages/fcl-web')
| -rw-r--r-- | packages/fcl-web/src/base/fphttpserver.pp | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/packages/fcl-web/src/base/fphttpserver.pp b/packages/fcl-web/src/base/fphttpserver.pp index d18b5a92a9..d664a5c559 100644 --- a/packages/fcl-web/src/base/fphttpserver.pp +++ b/packages/fcl-web/src/base/fphttpserver.pp @@ -88,8 +88,10 @@ Type TFPHTTPConnectionThread = Class(TThread) private FConnection: TFPHTTPConnection; + FThreadList: TThreadList; Public Constructor CreateConnection(AConnection : TFPHTTPConnection); virtual; + Constructor CreateConnection(AConnection : TFPHTTPConnection; AThreadList: TThreadList); Procedure Execute; override; Property Connection : TFPHTTPConnection Read FConnection; end; @@ -121,6 +123,7 @@ Type FServerBanner: string; FLookupHostNames, FThreaded: Boolean; + FConnectionThreadList: TThreadList; FConnectionCount : Integer; FUseSSL: Boolean; procedure DoCreateClientHandler(Sender: TObject; out AHandler: TSocketHandler); @@ -137,7 +140,7 @@ Type procedure SetQueueSize(const AValue: Word); procedure SetThreaded(const AValue: Boolean); procedure SetupSocket; - procedure WaitForRequests; + procedure WaitForRequests(MaxAttempts: Integer = 10); Protected // Override this to create descendent function CreateSSLSocketHandler: TSocketHandler; @@ -648,6 +651,14 @@ begin Inherited Create(False); end; +constructor TFPHTTPConnectionThread.CreateConnection(AConnection: TFPHTTPConnection; AThreadList: TThreadList); +begin + FThreadList := AThreadList; + if Assigned(FThreadList) then + FThreadList.Add(Self); + CreateConnection(AConnection); +end; + procedure TFPHTTPConnectionThread.Execute; begin try @@ -655,6 +666,8 @@ begin FConnection.HandleRequest; finally FreeAndNil(FConnection); + if Assigned(FThreadList) then + FThreadList.Remove(Self); end; except // Silently ignore errors. @@ -780,6 +793,8 @@ begin if FThreaded=AValue then exit; CheckInactive; FThreaded:=AValue; + if FThreaded and not Assigned(FConnectionThreadList) then + FConnectionThreadList:=TThreadList.Create; end; function TFPCustomHttpServer.CreateRequest: TFPHTTPConnectionRequest; @@ -811,7 +826,7 @@ end; function TFPCustomHttpServer.CreateConnectionThread(Conn: TFPHTTPConnection ): TFPHTTPConnectionThread; begin - Result:=TFPHTTPConnectionThread.CreateConnection(Conn); + Result:=TFPHTTPConnectionThread.CreateConnection(Conn, FConnectionThreadList); end; procedure TFPCustomHttpServer.CheckInactive; @@ -893,7 +908,7 @@ begin FCertificateData:=CreateCertificateData; end; -procedure TFPCustomHttpServer.WaitForRequests; +procedure TFPCustomHttpServer.WaitForRequests(MaxAttempts: Integer); Var FLastCount,ACount : Integer; @@ -901,7 +916,7 @@ Var begin ACount:=0; FLastCount:=FConnectionCount; - While (FConnectionCount>0) and (ACount<10) do + While (FConnectionCount>0) and (ACount<MaxAttempts) do begin Sleep(100); if (FConnectionCount=FLastCount) then @@ -957,10 +972,27 @@ begin end; destructor TFPCustomHttpServer.Destroy; +var + ThreadList: TList; + I: Integer; begin Active:=False; if Threaded and (FConnectionCount>0) then + begin + // first wait for open requests to finish and get closed automatically WaitForRequests; + // force close open sockets + ThreadList:=FConnectionThreadList.LockList; + try + for I:= ThreadList.Count-1 downto 0 do + CloseSocket(TFPHTTPConnectionThread(ThreadList[I]).Connection.Socket.Handle); + finally + FConnectionThreadList.UnlockList; + end; + // all requests must be destroyed - wait infinitely + WaitForRequests(High(Integer)); + end; + FreeAndNil(FConnectionThreadList); FreeAndNil(FCertificateData); inherited Destroy; end; |
