Indy 10:
两个线程,线程1在TIdHTTP上调用Get并阻止读取数据.
线程2将在同一TIdHTTP上调用disconnect以中断Get.
我在TIdHTTP上使用摘要式身份验证,我偶尔会得到一个AV.
线程1的callstack:
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的callstack:
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的最新代码并查看代码,我相信行为应该是相同的.
我相信从另一个线程断开调用是推荐的使用模式,我错了吗?这是Indy的一个错误吗?似乎有必要锁定断开连接,但很难看到可能造成的死锁.还有其他人遇到过这个吗?
解决方法
是的,您遇到的是竞争条件,两个线程在断开套接字时尝试释放相同的Request.Authentication对象两次.给定堆栈跟踪,两个线程必须在完全相同的时间断开套接字,因为如果IOHandler仍然打开,disconnect()仅调用DoOndisconnect(),并且在调用DoOndisconnect()之前关闭IOHandler.
您可以尝试执行的操作是使用OnStatus事件在hsdisconnecting状态中输入线程安全锁,例如临界区或互斥锁,并将锁保留在hsdisconnected状态.在这些状态之间调用IOHandler.Close()和DoOndisconnect(),这样就可以有效地序列化线程,这样它们就不能断开套接字并在同一时间释放Request.Authentication对象.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。