2008-05-11
IOCP 的资源释放问题
关键字: iocp
在参考了一些资料,并且尝试了几次之后,也逐渐想到了一个用来安全释放 IOCP 资源的办法。
http://groups.google.com/group/dev4server/browse_thread/thread/29a91064931a628e
接着发现有人已经把这种方案描述的很清楚了
http://blog.codingnow.com/2007/07/robust.html#comment-12142
对大家的讨论不置可否,但是使用ID代替指针确实在某些方面是有益处的。
而某些时候我们无法使用智能指针。举个例子,完成端口中
其中的lpKey是一个非常关键的变量,我们一般把它置为一个对象的指针。这样我们就可以通过这个指针去访问该对象。
但是事实上很多时候这个指针的生命周期是不固定的,而由于其传入的是PULONG_PTR类型的值,我们又不能直接使用智能指针。要么就要繁琐的执行addref 和 release 这样的操作而完全丢失智能指针的优越性。
可是,如果这里传入的是一个ID或者HANDLE,为其对象的访问增加一层间接性。那么我们就可以预防非法的指针访问,从而达到安全的生命周期管理。
http://groups.google.com/group/dev4server/browse_thread/thread/29a91064931a628e
接着发现有人已经把这种方案描述的很清楚了
http://blog.codingnow.com/2007/07/robust.html#comment-12142
对大家的讨论不置可否,但是使用ID代替指针确实在某些方面是有益处的。
而某些时候我们无法使用智能指针。举个例子,完成端口中
GetQueuedCompletionStatus( *pTHIS, &dwNumberBytes, (PULONG_PTR)&lpKey, &lpEvent, INFINITE );
其中的lpKey是一个非常关键的变量,我们一般把它置为一个对象的指针。这样我们就可以通过这个指针去访问该对象。
但是事实上很多时候这个指针的生命周期是不固定的,而由于其传入的是PULONG_PTR类型的值,我们又不能直接使用智能指针。要么就要繁琐的执行addref 和 release 这样的操作而完全丢失智能指针的优越性。
可是,如果这里传入的是一个ID或者HANDLE,为其对象的访问增加一层间接性。那么我们就可以预防非法的指针访问,从而达到安全的生命周期管理。
评论
iunknown
2008-05-12
之前一直困扰在如何等待所有这些异步 IO 操作完成(包括被取消),现在想到了一个办法。
IOCP 的内部实现是遵循 FIFO 的,在 closesocket 之后,不要立即 free ,而是重新
PostQueuedCompletionStatus 一个完成特殊事件给 GQCS ,通过 GQCS 得到这个事件,接着在进行 free 。
这样就相当于变相地等待所有这些异步 IO 完成了。
因为 closesocket 之后,所有 IO 都会被取消,这些取消的操作将在 GQCS 的队列中等待被处理,
而用 PostQueuedCompletionStatus 投递的特殊事件,应该排在这些被取消的操作之后。
IOCP 的内部实现是遵循 FIFO 的,在 closesocket 之后,不要立即 free ,而是重新
PostQueuedCompletionStatus 一个完成特殊事件给 GQCS ,通过 GQCS 得到这个事件,接着在进行 free 。
这样就相当于变相地等待所有这些异步 IO 完成了。
因为 closesocket 之后,所有 IO 都会被取消,这些取消的操作将在 GQCS 的队列中等待被处理,
而用 PostQueuedCompletionStatus 投递的特殊事件,应该排在这些被取消的操作之后。
iunknown
2008-05-11
使用 BoundsChecker 进行了检查,报了下面的这种错误。
从描述来看,应该是某段内存被释放之后,接着这段内存继续被程序进行了修改。
OutDbStr: HEAP[testiocpecho.exe]:
OutDbStr: HEAP: Free Heap block 123c1a0 modified at 123c1d4 after it was freed
OutDbStr: HEAP[testiocpecho.exe]:
OutDbStr: HEAP: Free Heap block 1680040 modified at 1680074 after it was freed
OutDbStr: Heap corruption detected at 0123C1A8
OutDbStr: HEAP[testiocpecho.exe]:
OutDbStr: HEAP: Free Heap block 123c1a0 modified at 123c1d4 after it was freed
http://msdn.microsoft.com/en-us/library/ms737582(VS.85).aspx
An application should not assume that any outstanding I/O operations on a socket will all be guaranteed to completed when closesocket returns. The closesocket function will initiate cancellation on the outstanding I/O operations, but that does not mean that an application will receive I/O completion for these I/O operations by the time the closesocket function returns. Thus, an application should not cleanup any resources (WSAOVERLAPPED structures, for example) referenced by the outstanding I/O requests until the I/O requests are indeed completed.
从上面这段描述来看, IOCP 在内部是这样处理的:
在 WSASend 和 WSARecv 发出一个异步请求之后,如果一直都没有完成,直到 closesocket 引发这些操作被取消,在取消的过程中,IOCP 会对 OVERLAPPED 进行一些写操作。但是 IOCP 又没有提供一种等待这些操作完成的机制。那应该如何来处理这种情况呢?
一种可能的办法是在 closesocket 之后,不要立即释放 OVERLAPPED ,重新 POST 一个 CompletionStats 到 CompletionPort ,通过 GQCS 再次得到这个 OVERLAPPED ,然后释放?期望 GQCS 内部是 FIFO 的?被取消的 IO 操作,比重新 POST 的 CompletionStats 更早发生,因此会被先处理?
从描述来看,应该是某段内存被释放之后,接着这段内存继续被程序进行了修改。
引用
OutDbStr: HEAP[testiocpecho.exe]:
OutDbStr: HEAP: Free Heap block 123c1a0 modified at 123c1d4 after it was freed
OutDbStr: HEAP[testiocpecho.exe]:
OutDbStr: HEAP: Free Heap block 1680040 modified at 1680074 after it was freed
OutDbStr: Heap corruption detected at 0123C1A8
OutDbStr: HEAP[testiocpecho.exe]:
OutDbStr: HEAP: Free Heap block 123c1a0 modified at 123c1d4 after it was freed
http://msdn.microsoft.com/en-us/library/ms737582(VS.85).aspx
引用
An application should not assume that any outstanding I/O operations on a socket will all be guaranteed to completed when closesocket returns. The closesocket function will initiate cancellation on the outstanding I/O operations, but that does not mean that an application will receive I/O completion for these I/O operations by the time the closesocket function returns. Thus, an application should not cleanup any resources (WSAOVERLAPPED structures, for example) referenced by the outstanding I/O requests until the I/O requests are indeed completed.
从上面这段描述来看, IOCP 在内部是这样处理的:
在 WSASend 和 WSARecv 发出一个异步请求之后,如果一直都没有完成,直到 closesocket 引发这些操作被取消,在取消的过程中,IOCP 会对 OVERLAPPED 进行一些写操作。但是 IOCP 又没有提供一种等待这些操作完成的机制。那应该如何来处理这种情况呢?
一种可能的办法是在 closesocket 之后,不要立即释放 OVERLAPPED ,重新 POST 一个 CompletionStats 到 CompletionPort ,通过 GQCS 再次得到这个 OVERLAPPED ,然后释放?期望 GQCS 内部是 FIFO 的?被取消的 IO 操作,比重新 POST 的 CompletionStats 更早发生,因此会被先处理?
发表评论
- 浏览: 79328 次

- 详细资料
搜索本博客
我的相册
vim
共 2 张
共 2 张
最近加入圈子
最新评论
-
集成 IOCP 到 Libevent
去找了 memcached for win32 的源代码,结果可以顺利编译,并且 ...
-- by iunknown -
集成 IOCP 到 Libevent
qiezi 写道GetQueuedCompletionStatusEx也支持超时 ...
-- by iunknown -
集成 IOCP 到 Libevent
GetQueuedCompletionStatusEx也支持超时,用它代替sel ...
-- by qiezi -
集成 IOCP 到 Libevent
linux/solaris上的aio有多种回调/通知方式,可能和libevent ...
-- by qiezi -
集成 IOCP 到 Libevent
SPServer是一个很不错的框架,受到启发,我用boost::asio实现了一 ...
-- by wow






评论排行榜