s = createsocket(); //假定s返回值是10
CreateIoCompletionPort(s, m_hCompletionPort, (DWORD_PTR)&A, 0);
WSASend(s,...);
WSASend(s,...);
WSASend(s,...);
WSASend(s,...);
WSASend(s,...);
这个时候,完成端口里累计了多条跟s相关的数据,由于完成端口的线程暂时繁忙,未来得及处理s关闭后的失败数据
closesocket(s);
s = createsocket(); //s的值仍然是10
CreateIoCompletionPort(s, m_hCompletionPort, (DWORD_PTR)&B, 0);
好了,本线程到此告一个段落,回到完成端口线程上来:
GetQueuedCompletionStatus(m_hCompletionPort,&dwTransferred,(LPDWORD)&pCustomData,(OVERLAPPED *) ...,INFINITE);
问:
pCustomData是指向A还是指向B?
在我的设计意识里,pCustomData应该指向A,且我没有再任何文档和论坛里看到提及此问题,且无论是官方的还是非官方的例子都是我这样的用法。
实际上,pCustomData指向了B
此时,WSASend(和其他函数)操作的数据和在GetQueuedCompletionStatus后处理的数据不再绑定到一致的数据上,bug由此产生,且无法直接观察,非常难重现,因为closesocket后也不是立即调用createsocket,且socket句柄被立即复用的概率实在不大,因为不是立即复用,完成端口线程就把老句柄相关的数据处理完毕了。
这个问题困扰<乱武>项目组和测试组人员至少三周,终在昨日(2008-8.31)获知原因并得到解决。老谢说值得庆贺,该出去搓一顿。吾深表赞同,不过就是要我买单有些许遗憾——因为代码是我写的。
2603

被折叠的 条评论
为什么被折叠?



