I am using ReadDirectoryChangesW
to monitor when a file has changed within a directory. I am using the asynchronous version of it with a completion routine function, (as per the docs).
Everything works fine until I wish to stop monitoring the folder.
To stop the monitoring I call the Close
function.
The problem is that I still get one last notification, but by then I have destroyed my LPOVERLAPPED
value.
How can I stop ReadDirectoryChangesW
and prevent my MyCompletionRoutine
function from being called.
// get the handle
_handle = CreateFileW( ... )
void Read()
{
...
ReadDirectoryChangesW( _handle, ..., &MyCompletionRoutine );
...
}
void Close()
{
::CancelIo(_handle );
::CloseHandle(_handle );
}
void __stdcall MyCompletionRoutine (
const unsigned long dwErrorCode,
const unsigned long dwNumberOfBytesTransfered,
_OVERLAPPED* lpOverlapped )
{
// ... do stuff and start a read again
Read();
}
In the code above I might have called Read
but I want to stop before MyCompletionRoutine
is called.
Not sure if that helps, but the error message I get is 317
You are closing your HANDLE
and freeing your OVERLAPPED
too soon.
CancelIo()
(and its cross-thread brother, CancelIoEx()
) simply mark active I/O operations as cancelled and then exit, but you still need to actually wait for those operations to fully complete before you can then free their OVERLAPPED
.
If an operation notices the cancellation before completing its work, it will stop its work and report a completion with an error code of ERROR_OPERATION_ABORTED
, otherwise it will finish its work normally and report a completion with the appropriate error code.
After calling CancelIo/Ex()
, you need to continue waiting on and handling completed operations, until there are no more operations left to wait on.
In other words, MyCompletionRoutine()
can indeed be called after CancelIo()
is called, and it needs to check for ERROR_OPERATION_ABORTED
before calling Read()
again. And if there is a pending read in progress when CancelIo()
is called, you need to wait for that read to complete.