Как бы то ни было, я пытаюсь выполнить асинхронный ReadDirectoryChangesW
с завершением ввода-вывода, и он не работает, в частности, GetLastError
неоднократно возвращает 258 ( GetQueuedCompletionStatus
тайм-аут).
У меня есть структуры:
typedef struct dirinfo_struct
{
HANDLE hDirFH; // directory handle
OVERLAPPED Overlapped; // overlapped storage
int len_buffer; // buffer length
wchar_t* buffer; // buffer itself
wchar_t* directory_name; // target name
} dirinfo_t;
typedef struct dirmon_struct
{
HANDLE hDirOPPort; // handle to the IO port.
dirinfo_t* dirinfo; // pointer to the struct above.
} dirmon_t;
для хранения соответствующей информации. Это инициализировано:
dirinfo_t* t = malloc(1*sizeof(dirinfo_t));
dirmon_t* d = malloc(1*sizeof(dirmon_t));
dirinfo_init(t); // does t->buffer = malloc(8192*sizeof(wchar_t));
Затем я создаю свой дескриптор каталога и com-порт:
t->hDirFH = CreateFile(L"C:\\test",
FILE_LIST_DIRECTORY,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
NULL);
d->dirinfo = t;
d->hDirOPPort = CreateIoCompletionPort(d->dirinfo->hDirFH,
NULL,
(ULONG_PTR)(d->dirinfo),
1);
Затем я передаю эту информацию через d в новый поток. Теперь о новом потоке, который у меня есть:
bResultQ = GetQueuedCompletionStatus(d->hDirOPPort, lpBytes,
(ULONG_PTR*)d->dirinfo,
lpOverlapped, 1000);
if ( bResultQ )
{
bResultR = ReadDirectoryChangesW(d->dirinfo->hDirFH,
(void*)d->dirinfo->buffer,
8192, TRUE,
FILE_NOTIFY_CHANGE_FILE_NAME |
FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_ATTRIBUTES |
FILE_NOTIFY_CHANGE_SIZE |
FILE_NOTIFY_CHANGE_LAST_WRITE |
FILE_NOTIFY_CHANGE_LAST_ACCESS |
FILE_NOTIFY_CHANGE_CREATION |
FILE_NOTIFY_CHANGE_SECURITY,
lpReadDirBytes,
&d->dirinfo->Overlapped,
NULL );
}
else
{
printf("GetQueuedCompletionStatus(): Failed, ");
errorcode = GetLastError();
printf("Error Code %d\n", errorcode);
Sleep(500);
}
Итак, я отключил его и с радостью получаю тайм-ауты (258 ошибок), как и должно, поскольку каталог не изменился. Однако даже если я изменю каталог, я все равно получаю сообщения об ошибках; Другими словами, эти изменения не принимаются. Это наводит меня на мысль, что я настроил это неправильно.
Есть идеи?
Предостережения:
ReadDirectoryChangesW
не вариант. Если никакие события не запускаются, мне нужен поток, в котором время ожидания истекло, чтобы он мог проверить, должен ли он по-прежнему работать. FindFirstChangeNotification
и т. Д. Тоже не вариант - я не хочу постоянно сравнивать списки каталогов, чтобы выяснить, что изменилось. Другие примечания:
Я взглянул на CDirectoryChangeWatcher из проекта кода, но не считая использования C ++ и многих других потоков, я не могу посмотреть, что я делаю иначе. Не стесняйтесь указать на это, если я что-то упускаю!
Вывод, если он помогает, в основном повторяется, независимо от того, сколько я изменяю каталог.
GetQueuedCompletionStatus(): Failed, Error Code 258