The docs and samples seem to indicate that GetOverlappedResult() only needs
to be called when one of the API's which take an OVERLAPPED object return
FALSE and GetLastError() returns ERROR_IO_PENDING. This is how I initially
implemented things. However, this wasn't sufficient. When ReadFile()
returns FALSE and GetLastError() returns ERROR_MORE_DATA appears to be
another case where you need to call GetOverlappedResult() because the
ReadFile() call did not return the number of bytes read. Am I correct about
this? Are there any other cases in which I should be calling
GetOverlappedResult()?
--
Thanks,
Nick
nickno...@community.nospam
remove "nospam" change community. to msn.com
Are you using I/O completion port in your application? There are several
ways to use I/O completion port in application. Using GetOverlappedResult()
is an old fashion way and is not recommended because it can not achieve
high multithreading performance such as scalability etc...
Below is the pseudocode of GetOverlappedResult(), as you can see it
internally uses WaitForSingleObject() API which will cause the calling
thread to block:
BOOL GetOverlappedResult(
HANDLE hfile,
OVERLAPPED* po,
PDWORD pdwNumBytes,
BOOL fWait) {
if (po->Internal == STATUS_PENDING) {
DWORD dwWaitRet = WAIT_TIMEOUT;
if (fWait) {
// Wait for the I/O to complete
dwWaitRet = WaitForSingleObject(
(po->hEvent != NULL) ? po->hEvent : hfile, INFINITE);
}
if (dwWaitRet == WAIT_TIMEOUT) {
// I/O not complete and we're not supposed to wait
SetLastError(ERROR_IO_INCOMPLETE);
return(FALSE);
}
if (dwWaitRet != WAIT_OBJECT_0) {
// Error calling WaitForSingleObject
return(FALSE);
}
}
// I/O is complete; return number of bytes transferred
*pdwNumBytes = po->InternalHigh;
if (SUCCEEDED(po->Internal)) {
return(TRUE); // No I/O error
}
// Set last error to I/O error
SetLastError(po->Internal);
return(FALSE);
}
If you are curious with GetOverlappedResult() using in I/O Completion Port,
you may refer to the articles below:
"IOCompletion Port Technique and Asynchoronos I/O Operartion"
http://www.codeproject.com/KB/IP/IOCompletionPort.aspx
"Writing Scalable Applications for Windows NT"
http://dev.rdxx.com/C/2005-9/13/202838873.shtml
A better approach is using GetQueuedCompletionStatus() API. I highly
recommend you to read "Receiving Completed I/O Request Notifications"
section of "Chapter2 Device I/O and Interthread Communication" in Jeffrey
Richter's classic book <Programming Server-Side Applications for Microsoft
Windows 2000>. This chapter is targeting the I/O completion port and talks
different ways of using it.
If I remember correct, the internet has the free download e-copy of this
book. Thanks.
Best regards,
Jeffrey Tan
Microsoft Online Community Support
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
msd...@microsoft.com.
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.
Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Regardless of which way I go I still need an answer to my original question.
And by the way, GetOverlappedResult() should not block as I pass FALSE as
the wait parameter.
--
Thanks,
Nick
nickno...@community.nospam
remove "nospam" change community. to msn.com
Thank you for the feedback.
Yes, you are safe to call GetOverlappedResult(). As the pseudocode
indicates, if you pass "FALSE" to the wait parameter, its net effect is
reading OVERLAPPED.InternalHigh field(which contains the number of bytes
transferred) and then checking OVERLAPPED.Internal to determine if the I/O
operation causes any error.
Once the OVERLAPPED.Internal field indicates no I/O error, the
OVERLAPPED.InternalHigh field is valid number of bytes transferred.
Thanks.
Best regards,
Jeffrey Tan
Microsoft Online Community Support
=========================================
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
msd...@microsoft.com.
This posting is provided "AS IS" with no warranties, and confers no rights.
In addition, I'm not checking any of the members of the OVERLAPPED
structure. GetOverlappedResult() returns the result and one of the formal
parameters is a pointer to the number of bytes transmitted.
--
Thanks,
Nick
nickno...@community.nospam
remove "nospam" change community. to msn.com
ret = ReadFile / WriteFile (hFile, ... pOverlapped) <- hEvent not NULL
if(ret == ERROR_IO_PEDING)
{
// do some work while the IO is in progress - possibly including WSFO /
WFMO on pOverlaped->hEvent
GetOverlapedResult(hFile, pOverlapped, ...)
}
This paradigm is only useful, IMHO, when you need to control IO timeouts /
cancelation in the UM app. For other situations, blocking IO or IOCP will
be more efficient by far and provide better functionality.
Look at ReadFile / WriteFile / GetOverlappedResult / CreateIoCompletionPort
in MSDN for more details
BTW: why are you using these functions in .NET? There are managed wrappers
for most things already.
"nickdu" <nickno...@community.nospam> wrote in message
news:7C82A82E-A33C-427C...@microsoft.com...
The .NET implementation you're talking about, is that
FileStream.BeginRead()/FileStream.EndRead()? If so, I'm not sure I get the
control I want from those methods. Also, the docs indicate that for anything
64K or less they are synchronous, again that might not be what I want. In
addition, I wrote a chunking stream implementation so that even for large
buffers I won't be reallocating/copying to fill up a buffer and I will stay
off the large object heap. Also, there is no managed version of
CreateNamedPipe(), WaitNamedPipe() for .NET 2.0.
--
Thanks,
Nick
nickno...@community.nospam
remove "nospam" change community. to msn.com
Yes - FileStream.BeginRead etc. was what I was refereeing to. And you are
right in that .NET does not have any pipe classes that I know of. Creating
a custom stream implementation is probably the best thing if you need a .NET
pipe server / client for some reason.
"nickdu" <nickno...@community.nospam> wrote in message
news:7D6BD6F4-F996-4DDE...@microsoft.com...
Just to follow up on your first statement, the case I mention does occur.
ReadFile() returns TRUE yet bytesTransferred is zero. When I call
GetOverlappedResult() that does return the correct number of bytes
transferred.
"nickdu" <nickno...@community.nospam> wrote in message
news:D54FC861-0FA2-416B...@microsoft.com...