|
| This newsletter contains archived content. No warranty is made as to technical accuracy of content or currency of URLs.
Your user-mode application is sending your driver lots of I/O requests, but the driver insists on handling the requests one at a time. What's the problem?
You might think that your driver is blocking in some obscure way or that you need more threads in your application, but the solution is often much simpler: Make sure your application has opened the device for overlapped I/O. Otherwise, the I/O Manager serializes I/O requests by synchronizing through a lock in the file object before dispatching the IRP. Even if your application uses multiple threads, only one request at a time (per file handle) will get through.
To enable overlapped I/O in an application, set dwFlagsAndAttributes with FILE_FLAG_OVERLAPPED when you call CreateFile to open the device. (If you skip this step you won't get overlapped I/O, even if you do everything else right.)
CreateFile returns a handle that can be used to access the device. When you call ReadFile, WriteFile, or DeviceIoControl with the file handle created by CreateFile, supply a pointer to an OVERLAPPED structure that contains a handle to an event object to signal when the operation completes. These functions return immediately for overlapped operations; the event object is signaled when the operation is completed.
Be sure to initialize the OVERLAPPED structure to zero before using it in a function call, and set only the members that are needed by the function. For example, the Offset member should be set for ReadFile and WriteFile calls, but this member should be zero for DeviceIoControl. Also, be sure to use a separate OVERLAPPED structure for each request; re-using the structure before the previous asynchronous operation has been completed can cause errors. Besides, your application will need the original structure to call HasOverlappedIoCompleted or GetOverlappedResult for the request.
After you've opened a device for overlapped I/O, can you simply omit the OVERLAPPED structure to get synchronous I/O? No, you must supply an OVERLAPPED structure for all function calls (read, write, or device control) with that handle. Passing NULL can lead to undefined behavior, even if the driver completes the request synchronously. For synchronous I/O, the OVERLAPPED structure can be declared on the stack as long as the application waits for the I/O to complete before returning.
For code snippets and additional details, read the driver tip on WHDC.
|