overlapped io is not in signalled state

Hi,

I am using overlapped structure for asynchronous IO. However very frequently i get this error Asynchronous IO is not in signaled state. To check the behaviour, I placed a break point both in EvtIoWrite call and EvtRequestWriteCompletionRoutine. The break point is hit in EvtIoWrite, but break point never reaches the EvtRequestwriteCompletion routine. It will hit only when I stop the application running. When will the Overlapped IO set to signalled state?

Thanks in advance

To add to above, this is the code I am using

OVERLAPPED ov;
memset(ov,0,sizeof(OVERLAPPED));
ov->hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
if(oh->hEvent == NULL)
{

}

OVERLAPPED ov;
memset(&ov, 0, sizeof(OVERLAPPED));
ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if(ov->hEvent == NULL)
{
unsigned int code = GetLastError();
char errmsg[256];

GetErrorMessage(code, errmsg, sizeof(errmsg));
SET_LAST_ERROR_STRING(“CreateEvent failed, error: 0x%x, error string: %s”, code, errmsg);

return false;
}

success = WriteFile(g_hDriver, data, sizeToWrite, (PULONG) sizeWritten, &ov);

if(success == 0)
{
unsigned int err = GetLastError();
if(err != ERROR_IO_PENDING)
{
return false;
}
}

while(0 == GetOverlappedResult(g_hDriver, ov, bytesReturned, FALSE))
{
code = GetLastError();
if(code != ERROR_IO_INCOMPLETE)
{
//error
GetErrorMessage(code,errmsg, sizeof(errmsg));
SET_LAST_ERROR_STRING(“GetOverlappedResult failed. error: 0x%x, error string: %s,Bytes returned %x”, code, errmsg,*bytesReturned);

return false;
}

if(GetTickCount() > endtime)
{
if(CancelIo(g_hDriver) == 0)
{
code = GetLastError();
GetErrorMessage(code, errmsg, sizeof(errmsg));
SET_LAST_ERROR_STRING(“CancelIO failed. error: 0x%x, error string: %s”, code, errmsg);
return false;
}
SET_LAST_ERROR_STRING(“Timed out waiting for asynchronous IO to finish”);
return false;
}
}

In which stack you place your driver? It looks that the lower driver doesn’t complete the request for some reasons.

When you close an application OS cancels thread’s asynch IRPs, so your request is completed with status CANCELED.

I am writing a WDF driver. The driver gets the writeIOrequest and completes the routine. But before the evtcompletionroutine call back function gets hit the getoverlapped function is returning as io not in signalled state. I thought till evtcompletionroutine callback is called the getoverlappedresult will always return evt_io_pending. is that not correct?

Did you call WdfRequestCompleteWithInformation for completing the request?

You use OVERLAPPED incorrectly. If WriteFile returns TRUE, OVERLAPPED may not be filled and the event may not be set.

Also, after you call CancelIo, you still NEED TO WAIT after that for the IO to complete.

I am calling WdfRequestCompleteWithInformation in the EvtCompletionRoutine. I will check with the CancelIO. I have debugged the problem further. After WriteFile request got succeded , I am calling ReadFile. (USB transmission). ReadFile call succeds. Then I do one more WriteFile which succeeds, but the next ReadFile call never succeds. I am sure the device has data at the IN endpoint. Is it because I have not done 1st ReadFile call incorrectly?

Are there are any freely awailable usb packet snoopers?

This is a very important point to keep in mind and a bug that must be fixed in the code that was posted.

Cancelling I/O is just a hint to the I/O manager to stop, it does not guarantee that by the time CancelIo returns, that the I/O has finished. Should you not wait for the I/O after cancellation, you’ll end up with very difficult to debug stack corruption.

  • S (Msft)

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@broadcom.com
Sent: Wednesday, July 25, 2012 7:51 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] overlapped io is not in signalled state

You use OVERLAPPED incorrectly. If WriteFile returns TRUE, OVERLAPPED may not be filled and the event may not be set.

Also, after you call CancelIo, you still NEED TO WAIT after that for the IO to complete.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

xxxxx@gmail.com wrote:

I am writing a WDF driver. The driver gets the writeIOrequest and completes the routine. But before the evtcompletionroutine call back function gets hit the getoverlapped function is returning as io not in signalled state. I thought till evtcompletionroutine callback is called the getoverlappedresult will always return evt_io_pending. is that not correct?

I just want to double-check on one thing in your description.

YOUR completion routine will never be called for a requests that YOU
complete. Is that what you are assuming? Your completion routine is
only called when a request that you submit to the driver BELOW you
completes.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

no. I am expecting that evtiocompletionroutine gets called after the request gets completed either success / timeout. What I did not understand is, when I call createEvent , the state of the event is not signalled. I am guessing the framework will set the event object to signalled state after the driver call (writefile). Is my understanding wrong?

The io manager will set the event when the PIRP completes back to the io manager. The WDFREQUEST in question here: are you sending it to another stack with a WDFIOTARGET or are you always keeping it within your driver and you complete it when done?

How are you registering your evtiocompletionroutine? What api are you calling?

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Wednesday, July 25, 2012 11:07 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] overlapped io is not in signalled state

no. I am expecting that evtiocompletionroutine gets called after the request gets completed either success / timeout. What I did not understand is, when I call createEvent , the state of the event is not signalled. I am guessing the framework will set the event object to signalled state after the driver call (writefile). Is my understanding wrong?


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

The request will always be in my driver. I use the request to call WdfRequestSend call. For which I have a iocompletion routine. So only when the WdfRequestCompleteWithInformation call is made then the event is set ?

This statement
The request will always be in my driver.

and this statement
I use the request to call WdfRequestSend call.

are kind of mutually exclusive. once you send the request with WdfRequestSend (that is not fire and forget), you must register a completion routine and within that completion routine, call one of the WdfRequestComplete APIs

d

xxxxx@gmail.com wrote:

The request will always be in my driver. I use the request to call WdfRequestSend call. For which I have a iocompletion routine. So only when the WdfRequestCompleteWithInformation call is made then the event is set ?

Are you are sending the request to yourself? If so, why? If not, then
as soon as you call WdfRequestSend, the request no longer belongs to
your driver. You can’t touch it until it comes back to you, via a
completion routine.

The event will be set only after ALL of the drivers in the stack have
completed it. The request has to bubble all the way back up to the I/O
manager.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

I am sorry to put it that way. Yes, the implementation is as u specified above. WdfRequestSend returns immediately. If the completion routine is not called immediately, the control returns to user mode. I call getoverlappedresult method and wait for either timeout / event completion like below

while(0 == GetOverlappedResult(g_hDriver, ov, bytesReturned, FALSE))
{
code = GetLastError();
if(code != ERROR_IO_INCOMPLETE)
{
//error
GetErrorMessage(code,errmsg, sizeof(errmsg));
SET_LAST_ERROR_STRING(“GetOverlappedResult failed. error: 0x%x,
error string: %s,Bytes returned %x”, code, errmsg,*bytesReturned);

return false;
}

if(GetTickCount() > endtime)
{
if(CancelIo(g_hDriver) == 0)
{
code = GetLastError();
GetErrorMessage(code, errmsg, sizeof(errmsg));
SET_LAST_ERROR_STRING(“CancelIO failed. error: 0x%x, error
string: %s”, code, errmsg);
return false;
}
SET_LAST_ERROR_STRING(“Timed out waiting for asynchronous IO to
finish”);
return false;
}
}

But the problem is the first time I am calling getoverlappedresult, the result is 0 with error code overlapped io is not in signalled state.

>running. When will the Overlapped IO set to signalled state?

OVERLAPPED::hEvent aka Irp->UserEvent is signaled in IopCompleteRequest


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

  1. Polling GetOverlappedResult is bad idea in general. Just call it with bWait TRUE.
  2. What exact GetLastError code are you getting? If it’s ERROR_IO_INCOMPLETE, it’s normal.
  3. MAKE SURE TO WAIT FOR IO COMPLETION AFTER CancelIo call.

My beliefis that the event is set to nonsigaled state by the I/O Manager
before te IRP is sent to the driver, and st to the signaled state by the
I/O Manager after the IRP is completed.

As to its creation state, it can be signaled or nonsignaled; this is one
of the parameters to CreateEvent
joe

no. I am expecting that evtiocompletionroutine gets called after the
request gets completed either success / timeout. What I did not understand
is, when I call createEvent , the state of the event is not signalled. I
am guessing the framework will set the event object to signalled state
after the driver call (writefile). Is my understanding wrong?


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

OVERLAPPED ov = {0};

Using memset is so 1975ish. Use ::ZeroMemory. But you don’t need to if
you use the initialization clause; it explicitly sets the first member to
0 and implicitly sets the rest of the structure to 0.
By the way, the first parameter would be &ov, or it wouldn’t even compile.
joe

To add to above, this is the code I am using

OVERLAPPED ov;
memset(ov,0,sizeof(OVERLAPPED));
ov->hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
if(oh->hEvent == NULL)
{

}


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer