ReadDirectoryChangesW: как обнаружить переполнение буфера при асинхронном использовании?
Я использую ReadDirectoryChangesW (Windows API) асинхронно в сочетании с GetQueuedCompletionStatus. Как я могу обнаружить возможное переполнение буфера, чтобы понять, что по крайней мере одно событие изменения файловой системы было потеряно?
3 ответа
Когда используешь ReadDirectoryChangesW
асинхронно, вы получите первую группу событий, затем вам придется вызывать ее снова, чтобы получить больше событий. Наличие большего количества событий, чем помещается в ваш буфер, не является ошибкой. Наличие большего количества событий, чем умещается в буфере уровня ОС, является условием ошибки, и вы обнаружите, что так:
- Случается какое-то событие.
- Асинхронная операция, начатая
ReadDirectoryChangesW
завершается успешно. Ваш буфер заполнен, ваш дескриптор события установлен или IOCP запущен. - Происходят дополнительные события, которые хранятся в буфере уровня ОС.
- Происходит больше дополнительных событий, которые переполняют буфер уровня ОС. Это не меняет статус операции с перекрытием, которая уже была выполнена на шаге 2.
- Вы ждете обработчик события или обрабатываете IOCP и обнаруживаете завершенный вызов OVERLAPPED.
- Ты звонишь
ReadDirectoryChangesW
еще раз, чтобы начать асинхронную перекрытую операцию проверки любых событий, которые произошли после шага 2. Этот вызов завершается неудачно синхронно, сGetLastError() == ERROR_NOTIFY_ENUM_DIR
или успешно сdwBytesTransferred == 0
, поскольку в документации сказано, что это также означает пересчет каталога
Если количество переданных байтов равно нулю, буфер был либо слишком большим для размещения системы, либо слишком маленьким, чтобы предоставить подробную информацию обо всех изменениях, произошедших в каталоге или поддереве. В этом случае вы должны вычислить изменения, перечислив каталог или поддерево.
Возможно, вам не удастся выполнить ваши обнаружения таким образом, но вот отличный учебник, который может помочь.
Вы также можете проверить ответ на этот другой вопрос.
Исходя из этого, похоже, что такой код ошибки не возвращается асинхронно.
Предложение: Мониторинг изменений синхронно, но в отдельном потоке, и следите за ERROR_NOTIFY_ENUM_DIR
,