IOCP ioqueue

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 19 Jul 2012 08:25:51 +0700 Benny Prijono <bennylp at teluu.com>
wrote:

> On Wed, Jul 18, 2012 at 6:49 PM, Timo Teras <timo.teras at iki.fi> wrote:
> 
> > Hi,
> >
> > This is slightly disappointing. IOCP is way better on Windows than
> > the select() based things. And as I noted before the select()
> > thingy is quite broken too.
> >
> > I would really prefer the simple race condition to be fixed, and
> > IOCP to be enabled by default on windows.
> >
> >
> I would prefer that too. But if you read the ticket, it's pretty
> difficult to solve, or at least for me, since the problem is not on
> us. If it's simple for you then by all means share a patch. :)

It seems that there has been a misunderstanding how the Windows async
IO works.

The OVERLAPPED structure is owned by windows API until the
corresponding notification is sent by the API. That is, even when the
request gets cancelled - you will always get the notification that it
was cancelled. Your code must not use or free the OVERLAPPED structure
*or* the data buffer it refers to until the matching reply is received.
That is even CancelIo is asynchronous; and when doing CloseHandle,
CancelIoEx is implied.

Thus you should not reuse OVERLAPPED structures until it has been acked
by windows.

Reference reading:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363789%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365683%28v=vs.85%29.aspx
http://www.osronline.com/showthread.cfm?link=213975

As short summary:
 1. CloseHandle will synchronously post the IO cancellations.
 2. OVERLAPPED updates are done asynchronously in usermode APCs so
    it is not guaranteed that all these are updated when CloseHandle
    returns.
 3. Thus you must not touch/free OVERLAPPED structures or the buffers
    they refer to until you get the completion message handled for them.

On older Windowses it may have *seemed* that the notification is
handled before CloseHandle returns. But that has been only because of
luck in how scheduler has decided to execute your threads.

Solutions that come up to my mind:

 - if the pool is deleted, the destructor should wait synchronously that
   each cancel notification is received before continuing

 - or async version: increase pool refcount everytime async operation
   is posted, and decrease it when an iocp notification is received

 - the OVERLAPPED structures *and* databuffers could be kept on separate
   pool managed by ioqueue, so the memory will not get freed too early.

-Timo



[Index of Archives]     [Asterisk Users]     [Asterisk App Development]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [Linux API]
  Powered by Linux