Точно как это звучит, я пытаюсь асинхронно ReadDirectoryChangesW
с IO Completion и не работает, в частности, GetLastError
многократно возвращает 258 (GetQueuedCompletionStatus
timeout).
У меня есть структуры:
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));
Затем я создаю папку Directory и 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 ошибок), как и следовало, поскольку каталог не изменился. Однако, даже если я изменяю каталог, я все равно получаю сообщения об ошибках; другими словами, эти изменения не собираются. Это заставляет меня поверить, что я неправильно настроил это.
Любые идеи?
Предостережения:
- По иронии судьбы, это в конечном итоге будет преобразовано в Python через pywin32. Однако, пока я не пойму, как это должно работать на C, я не пойду туда.
- Синхронный
ReadDirectoryChangesW
не является параметром. Если никакие события не запущены, мне нужен поток, который включен для тайм-аута, чтобы он мог проверить, все ли он должен работать. - Я пишу в C специально, а не С++.
-
FindFirstChangeNotification
и т.д. тоже не вариант. Я не хочу постоянно сравнивать списки каталогов, чтобы определить, что изменилось.
Другие примечания:
- Каталог существует, этот дескриптор не является NULL. Аналогично для дескриптора comport.
- Все, что передается в поток
Я рассмотрел CDirectoryChangeWatcher из проекта кода, но использование С++ и многих других потоков в стороне, я не вижу, что Я делаю по-другому. Не стесняйтесь указать на это, если я что-то упустил!
Выход, если он помогает, в основном повторяется, независимо от того, насколько я изменяю данный каталог.
GetQueuedCompletionStatus(): Failed, Error Code 258