Асинхронный ReadDirectoryChangesW - GetQueuedCompletionStatus всегда истекает по времени ожидания

Как бы то ни было, я пытаюсь выполнить асинхронный 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 ошибок), как и должно, поскольку каталог не изменился. Однако даже если я изменю каталог, я все равно получаю сообщения об ошибках; Другими словами, эти изменения не принимаются. Это наводит меня на мысль, что я настроил это неправильно.

Есть идеи?

Предостережения:

  • Как ни странно, это в конечном итоге будет преобразовано в Python через pywin32. Однако, пока я не пойму, как это должно работать в C, я туда не пойду.
  • Синхронный ReadDirectoryChangesW не вариант. Если никакие события не запускаются, мне нужен поток, в котором время ожидания истекло, чтобы он мог проверить, должен ли он по-прежнему работать.
  • Я пишу на C, а не на C ++.
  • FindFirstChangeNotification и т. Д. Тоже не вариант - я не хочу постоянно сравнивать списки каталогов, чтобы выяснить, что изменилось.

Другие примечания:

  • Каталог существует, этот дескриптор не равен NULL. То же самое и для дескриптора компорта.
  • Все передается в поток

Я взглянул на CDirectoryChangeWatcher из проекта кода, но не считая использования C ++ и многих других потоков, я не могу посмотреть, что я делаю иначе. Не стесняйтесь указать на это, если я что-то упускаю!

Вывод, если он помогает, в основном повторяется, независимо от того, сколько я изменяю каталог.

GetQueuedCompletionStatus(): Failed, Error Code 258

10
задан 27 May 2011 в 13:38
поделиться