WFSO on a handle is a practice which is actively discouraged by Microsoft,
for the reasons you state. There are two alternatives, one is to create an
Event object, which allows you to WaitForMultipleObjects (WFMO) on the array
of handles for the events, but a better solution is to use an I/O Completion
Port, where a thread handles the completion notifications and you identify
the I/O request via its OVERLAPPED object. It works like this
typedef struct {
OVERLAPPED ovl;
.your fields here.
} MYOVERLAPPED, *PMYOVERLAPPED;
PMYMOVERLAPPED myovl = new PMYOVERLAPPED;
or
PMYOVERLAPPED myovl = (PMYOVERLAPPED)malloc(sizeof(MYOVERLAPPED));
[The first is for C++ apps, the second for C apps]
Now, fill in the fields, in particular, make sure that the
myovl->ovl.hEvent = NULL;
and that the high and low values are set to 0 if you are not using them.
Then do
SomeIoOperation(,., myovl);
Now, in your handler, you do
UINT MyHandlerThread(LPVOID)
{
while(TRUE)
{ /* handler loop */
PMYOVERLAPPED myovl;
DWORDS bytesTransferred;
ULONG_PTR key;
BOOL b = GetQueuedCompletionStatus(iocp,
&bytesTransferred,
&key,
(LPOVERLAPPED)&myovl,
INFINITE);
if(!b)
{
// deal with error
}
else
{
use the key, bytesTransferred, and fields in myovl to deal
with that came back, e.g.,
if(key == INVALID_HANDLE_VALUE)
break;
.other stuff
delete myovl; // or in C, free(myovl);
} /* handler loop */
return 0;
} // MyHandlerThread
This is a sample. To shut the loop down, I do
PostQueuedCompletionStatus(iocp, 0,
(UINT_PTR)INVALID_HANDLE_VALUE, NULL);
Essentially, once you decide how you are encoding your keys (and I most
commonly use the handle as the IOCP key, so it will never be the out-of-band
INVALID_HANDLE_VALUE), you know which key values are illegal, and you
designate one of those to be your shutdown event. You can read more about
IOCPs on my MVP Tips site, www.flounder.com/mvp_tips.htm.
joe
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@emc.com
Sent: Monday, July 11, 2011 3:58 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] User / Kernel concurrent IOCTLs
Hello,
Is there a way to send asynchronous IOCTLs from user to kernel w/o using
overlapped IOs ?
If I use FILE_FLAG_OVERLAPPED when I use CreateFile, I still have to use
WaitForSingleObject with the handle to the event I got when I sent the
IOCTL.
This complicates things if I want to send multiple IOCTLs before waiting the
completion of any of them. It means I have to somehow remember all the
handles I got and wait for them to complete.
I am well aware that due to user/kernel limitation we can’t have a simple
completion function but I was wondering if there is a more elegant way to
send concurrent IOCTLs and wait for their completion.
Thanks.
Shay
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