Quantcast
Channel: The Old New Thing
Viewing all articles
Browse latest Browse all 24428

re: You can use an OVERLAPPED structure with synchronous I/O, too

$
0
0

I believe the canonical implementation reads like this (in Delphi):

// Returns when <BytesToRead> bytes are read into <Buffer> or when the timer <TimeoutTimer> expires,

// whatever comes first. The number of bytes read is returned.

// I/O errors are reported as EOSError exception.

function TTestObj.Read(TimeoutTimer: TWaitableTimer; out Buffer; BytesToRead: cardinal): cardinal;

var

 Handles: array [0..1] of THandle;

begin

 // ReadFile can complete immediately:

 if not Windows.ReadFile(FHandle, Buffer, BytesToRead, Result, @FOverlapped) then begin

Win32Check(Windows.GetLastError = ERROR_IO_PENDING, 'ReadFile');

// ReadFile will complete asynchronous => wait for it with a timeout:

Handles[0] := FOverlapped.hEvent;

Handles[1] := TimeoutTimer.Handle;

case Windows.WaitForMultipleObjects(length(Handles), pointer(@Handles), false, INFINITE) of

WAIT_OBJECT_0 + 0: // ReadFile is complete

 {do nothing};

WAIT_OBJECT_0 + 1: // timeout is expired => terminate the ReadFile operation:

 Win32Check( Windows.CancelIo(FHandle), 'CancelIo');

else

 RaiseWin32Error(Windows.GetLastError, 'WaitForMultipleObjects');

end;

// Get the result of the ReadFile operation. ERROR_OPERATION_ABORTED means CancelIO was called, but even in this case,

// we want to report the number of bytes read:

if not Windows.GetOverlappedResult(FHandle, FOverlapped, Result, false) and (Windows.GetLastError <> ERROR_OPERATION_ABORTED) then

 Win32Check(false, 'GetOverlappedResult/ReadFile');

 end;

end;

FHandle and FOverlapped are instance members. Win32Check() raises the EOSError exception when the condition (the first argument) is not true. <Result> is the implicit variable that represents the return value of the function.

I use this code in a productive application without problems.


Viewing all articles
Browse latest Browse all 24428

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>