views:

257

answers:

2

When I write a program about IO completion port in Windows Vista, the first sample didn't work and the GetQueuedCompletionStatus() can not get any OVERLAPPED structures.

So I put the OVERLAPPED structure in global scope,and it works amazingly. Why is that?

CODE1:

int main()
{
    OVERLAPPED o;
    ..
    CreateIoCompletionPort(....);

    for (int i = 0; i<10; i++)
    {
        WriteFile(..,&o);

        OVERLAPPED* po;
        GetQueuedCompletionStatus(..,&po);
    }


}

CODE2:

OVERLAPPED o;

int main()
{

    ..
    CreateIoCompletionPort(....);

    for (int i = 0; i<10; i++)
    {
        WriteFile(..,&o);

        OVERLAPPED* po;
        GetQueuedCompletionStatus(..,&po);
    }


}
+1  A: 

Okay! This is from the OVERLAPPED structure's MSDN page's Remarks section:

Any unused members of this structure should always be initialized to zero before the structure is used in a function call. Otherwise, the function may fail and return ERROR_INVALID_PARAMETER.

Globals are zero initializes whereas locals are not. If you plan to use the former code, you need to zero out the memory:

int main() {
    OVERLAPPED o = {0}; 
    // ...
dirkgently
In the former program, the GetQueuedCompletionStatus() just wait there until time is out. It seems there 's no way I can call GetLastError().
Jinx
A: 

Vista has a new Thread Poll API.

That's probably why the example you have is not working.

Read here: http://msdn.microsoft.com/en-us/library/ms686760(v=VS.85).aspx

"The new thread pool API provides more flexibility and control than the original thread pool API. However, there are a few subtle but important differences. In the original API, the wait reset was automatic; in the new API, the wait must be explicitly reset each time. The original API handled impersonation automatically, transferring the security context of the calling process to the thread. With the new API, the application must explicitly set the security context....."

vilaca