在忙于以重叠模式使用Windows套接字并使用完成例程(因此没有IOCP)获取反馈的时候,我发现了以下奇怪的情况:
listen
和AcceptEx
打开服务器套接字。ConnectEx
我们现在(至少)有3个套接字:1个列出套接字,一个客户端连接的套接字和一个服务器连接的套接字。
传输一些数据后,我们用shutdown
关闭服务器和客户端连接的套接字。完成此步骤后,两个套接字均用closesocket
关闭。
当前:为确保没有等待完成的例程,我发出以下命令(伪代码):
while SleepEx(0,TRUE)== WAIT_IO_COMPLETION做;
我认为现在可以节省OVERLAPPED
和WSARecv
使用的WSASend
结构的内存。
此刻之后,当线程再次变为可警告状态时,将为服务器连接的套接字执行另一个完成例程回调,错误为10053,但使用我们刚刚释放的OVERLAPPED
结构。这是释放内存后的使用。
问题:
何时可以确定不再使用通过完成例程使用重叠IO的套接字发出完成回调呢?
答案 0 :(得分:2)
您需要等待I / O完成(关闭套接字将取消未完成的请求,并且您将获得完成回调)。
直到事件完成(通过等待hEvent
或接收APC)进行同步之前,操作系统拥有OVERLAPPED结构和关联的缓冲区的所有权。在收到此回调之前,您不能对缓冲区执行任何操作,并且绝对不能释放它。等待操作系统告知您不再需要它。
请注意,取消并不一定会立即导致完成,因为驱动程序可能正在与硬件请求同步,并且仅在硬件状态更改时才将IRP标记为完成。 (如果正在使用DMA,这将是必要的,但可能只是为了保持一致性而进行其他操作),因此,不能保证您显示的SleepEx
循环会收集所有取消信息。
跟踪待处理操作的每个套接字,并使用WaitForSingleObjectEx
而不是SleepEx
来显式地等待每个套接字。