ReadDirectoryChangesW: как обнаружить переполнение буфера при асинхронном использовании?

Я использую ReadDirectoryChangesW (Windows API) асинхронно в сочетании с GetQueuedCompletionStatus. Как я могу обнаружить возможное переполнение буфера, чтобы понять, что по крайней мере одно событие изменения файловой системы было потеряно?

3 ответа

Решение

Когда используешь ReadDirectoryChangesW асинхронно, вы получите первую группу событий, затем вам придется вызывать ее снова, чтобы получить больше событий. Наличие большего количества событий, чем помещается в ваш буфер, не является ошибкой. Наличие большего количества событий, чем умещается в буфере уровня ОС, является условием ошибки, и вы обнаружите, что так:

  1. Случается какое-то событие.
  2. Асинхронная операция, начатая ReadDirectoryChangesW завершается успешно. Ваш буфер заполнен, ваш дескриптор события установлен или IOCP запущен.
  3. Происходят дополнительные события, которые хранятся в буфере уровня ОС.
  4. Происходит больше дополнительных событий, которые переполняют буфер уровня ОС. Это не меняет статус операции с перекрытием, которая уже была выполнена на шаге 2.
  5. Вы ждете обработчик события или обрабатываете IOCP и обнаруживаете завершенный вызов OVERLAPPED.
  6. Ты звонишь ReadDirectoryChangesW еще раз, чтобы начать асинхронную перекрытую операцию проверки любых событий, которые произошли после шага 2. Этот вызов завершается неудачно синхронно, с GetLastError() == ERROR_NOTIFY_ENUM_DIR или успешно с dwBytesTransferred == 0, поскольку в документации сказано, что это также означает пересчет каталога

Если количество переданных байтов равно нулю, буфер был либо слишком большим для размещения системы, либо слишком маленьким, чтобы предоставить подробную информацию обо всех изменениях, произошедших в каталоге или поддереве. В этом случае вы должны вычислить изменения, перечислив каталог или поддерево.

Возможно, вам не удастся выполнить ваши обнаружения таким образом, но вот отличный учебник, который может помочь.

Вы также можете проверить ответ на этот другой вопрос.

Исходя из этого, похоже, что такой код ошибки не возвращается асинхронно.

Предложение: Мониторинг изменений синхронно, но в отдельном потоке, и следите за ERROR_NOTIFY_ENUM_DIR,

Другие вопросы по тегам