HasOverlappedIoCompleted()
ReadFileEx()
およびで開始された非同期I/Oでは機能しませんWriteFileEx()
。下部のコードスニペットはこれを示しています。この例でReadFileEx()
は、入力のないパイプから読み取るため、読み取りは完了しません。ただし、HasOverlappedIoCompleted()
TRUEを返します。呼び出しをオーバーラップに変更すると、ReadFile()
期待HasOverlappedIoCompleted()
どおりにFALSEが返されます。
私の質問は、コールバック自体に依存せずに、コールバックと重複したI / O要求が完了したかどうかを確認するにはどうすればよいですか?私のアプリケーションでは、APCはキューに入れられている可能性がありますが、アプリケーションがアラート可能な状態でまだ待機していない可能性があるため、必ずしも実行されている必要はありません。
ありがとう。
(GetOverlappedResult()は役に立ちません-TRUEも返します。)
もう少し背景:ReadFileEx()
問題を簡単に示すことができるため、私が使用している例では。私のアプリケーションではWriteFileEx()
、パイプインスタンスを繰り返し呼び出しています。前のメッセージWriteFileEx()
がまだ完了していない場合は、メッセージを送信するのではなくドロップする必要があります(同じパイプインスタンスに複数の保留中の書き込みがないようにする必要があります)が、前のメッセージがWriteFileEx()
完了している場合は、次のメッセージを開始する必要があります。完了コールバックはまだ実行されていません。
編集:問題のシナリオの説明
- スレッドはアラート可能状態になります(1つの読み取りAPCがキューに入れられます)。
- 読み取りAPCが開始されます。WriteFileEx()をキューに入れ、「書き込み保留」フラグを設定します。次に、ReadFileEx()をキューに入れます。
- メインスレッドが作業を開始します(アラート不可)。
- キューに入れられた読み取りが完了します。
- キューに入れられた書き込みが完了します(読み取り後)。
- メインスレッドはアラート状態になります。
- 読み取りAPCはキューの最初にあるため、最初に実行されます。「書き込み保留中」フラグを調べ、まだ設定されているため、書き込みをドロップします。実際、WriteFileEx()は完了しましたが、ReadFileEx()が最初に完了したため、まだAPCを呼び出していません。
カスタムの「書き込み保留」フラグをテストする代わりに、APCがまだ実行されていない場合でも、WriteFileEx()が実際に完了したかどうかをOSから確認したいと思います。
#include <Windows.h>
#include <stdio.h>
#include <assert.h>
VOID CALLBACK readComplete(DWORD err, DWORD bytes, LPOVERLAPPED ovlp)
{
}
int main(int argc, char *argv[])
{
HANDLE hServer;
OVERLAPPED serverOvlp = { 0 };
HANDLE hClient;
DWORD bytes;
BYTE buffer[16];
BOOL result;
hServer = CreateNamedPipe("\\\\.\\pipe\\testpipe", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, 0, 0, 5000, NULL);
serverOvlp.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
ConnectNamedPipe(hServer, &serverOvlp);
assert(GetLastError() == ERROR_IO_PENDING);
hClient = CreateFile("\\\\.\\pipe\\testpipe", GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL);
GetOverlappedResult(hServer, &serverOvlp, &bytes, TRUE);
/* Server starts an overlapped read */
// result = ReadFile(hServer, buffer, sizeof(buffer), &bytes, &serverOvlp);
result = ReadFileEx(hServer, buffer, sizeof(buffer), &serverOvlp, readComplete);
if (HasOverlappedIoCompleted(&serverOvlp))
{
puts("Completed");
}
else
{
puts("Not completed");
}
return EXIT_SUCCESS;
}