5

インディ10:

2つのスレッド、スレッド1はTIdHTTPでGetを呼び出し、データの読み取りをブロックしています。スレッド2は、Getを中断するために、同じTIdHTTPでdisconnectを呼び出します。

TIdHTTPでダイジェスト認証を使用していますが、ときどきAVを取得します。

スレッド1のコールスタック:

40491D [system.pas][System][@ClassDestroy][8989]
69EF2B [..\..\common\IdAuthenticationDigest.pas][IdAuthenticationDigest][TIdDigestAuthentication.Destroy][109]
404567 [system.pas][System][TObject.Free][8313]
6A2B69 [..\..\Common\IdHTTP.pas][IdHTTP][TIdCustomHTTP.DoOnDisconnected][1587]
534574 [IdTCPConnection.pas][IdTCPConnection][TIdTCPConnection.Disconnect][532]
534B3B [IdTCPConnection.pas][IdTCPConnection][TIdTCPConnection.Disconnect][767]
6A3FB3 [..\..\Common\IdHTTP.pas][IdHTTP][TIdCustomHTTP.DoRequest][2101]

スレッド2のコールスタック:

402BA3 [system.pas][System][@FreeMem][2477]
404521 [system.pas][System][TObject.FreeInstance][8294]
40491D [system.pas][System][@ClassDestroy][8989]
69EF2B [..\..\common\IdAuthenticationDigest.pas][IdAuthenticationDigest]        [TIdDigestAuthentication.Destroy][109]
404567 [system.pas][System][TObject.Free][8313]
6A2B69 [..\..\Common\IdHTTP.pas][IdHTTP][TIdCustomHTTP.DoOnDisconnected][1587]
534574 [IdTCPConnection.pas][IdTCPConnection][TIdTCPConnection.Disconnect][532]
534B3B [IdTCPConnection.pas][IdTCPConnection][TIdTCPConnection.Disconnect][767]

基本的に、DoRequestの最後に、切断されます。Request.Authenticationを解放しようとしている切断に競合状態があるようです。

Indy 10の最新のコードをダウンロードし、コードを見ると、動作は同じであるはずです。

別のスレッドからdisconnectを呼び出すことが推奨される使用パターンだと思いますが、間違っていますか?これはインディのバグですか?切断をロックする必要があるようですが、どのようなデッドロックが発生するかを確認するのは困難です。他の誰かがこれに遭遇しましたか?

4

1 に答える 1

6

Request.Authenticationはい、発生しているのは、ソケットが切断されているときに両方のスレッドが同じオブジェクトを2回解放しようとする競合状態です。スタックトレースを考えると、がまだ開いていて、が呼び出される前に閉じられている場合にDisconnect()のみ呼び出すため、両方のスレッドがまったく同時にソケットを切断する必要があります。DoOnDisconnect()IOHandlerIOHandlerDoOnDisconnect()

試してみることができるのは、OnStatusイベントを使用して、クリティカルセクションやミューテックスなどのスレッドセーフロックを状態に入れhsDisconnecting、ロックをhsDisconnected状態のままにすることです。 これらの状態の間に呼び出されるため、スレッドが効果的にシリアル化されるため、ソケットを切断してオブジェクトをまったく同時に解放することはできなくなりIOHandler.Close()ます。DoOnDisconnect()Request.Authentication

于 2012-09-20T19:05:17.440 に答える