ISAPI形式(DLL)のDataSnapサーバーでアプリケーションプールを停止するとアクセス違反が発生する
対象となるIDE製品
- Delphi XE4 ~ XE7
問題
Datasnapサーバーの実行形式として、IIS上で実行するISAPI(DLL)でDatasnapサーバーを実行している場合、IISのアプリケーションプールを停止すると、アクセス違反が発生します。
例えば、以下の手順でIISのアプリケーションプールを停止すると、Windowsのイベントログにアクセス違反が記録されます。
- IISへDataSnap DLLをデプロイ
- クライアントからIISへアクセス (w3wp.exeがロードされていることを確認)
- アプリケーションプールを停止(w3wp.exeがアンロードされていることを確認)
- [管理ツール]-[イベントビューア]-[Windowsログ]-[アプリケーション]のログを確認
解決
本症状は、デストラクタ内で解放済みのインスタンスを呼び出そうとして例外が発生しています。
XE8では、この不具合は修正済みです。
XE8以前のバージョンでこの問題を解決するには、以下のユニットファイルを修正し、自身のプロジェクトへ組み込んでください。
修正するファイル名(Data.DBXCommon.pas)
//(修正前)
destructor TDBXScheduler.Destroy;
begin
StopSchedulerThread;
CloseScheduler;
FEventSemaphore.Free;
FSync.Free;
FEvents.Free;
FThread.Free;
FThreadLock.Free;
inherited;
end;
//(修正後)
destructor TDBXScheduler.Destroy;
begin
StopSchedulerThread;
CloseScheduler;
FEventSemaphore.Free;
FSync.Free;
FEvents.Free;
FThread.Free;
FThreadLock.Free;
if FInstance = Self then //追加
FInstance := nil; //追加
inherited;
end;
修正するファイル名(Datasnap.DSHTTP.pas)
//(修正前)
destructor TDSHTTPServer.Destroy;
begin
if Assigned(FSessionEvent) then
TDSSessionManager.Instance.RemoveSessionEvent(FSessionEvent);
FreeAndNil(FTunnelService);
inherited;
end;
//(修正後)
destructor TDSHTTPServer.Destroy;
begin
if Assigned(FSessionEvent) then
if TDSSessionManager.Instance <> nil then //追加
TDSSessionManager.Instance.RemoveSessionEvent(FSessionEvent);
FreeAndNil(FTunnelService);
inherited;
end;