Вот несколько упрощенных примеров кода, объясняющих мой вопрос:
bool Signaled(HANDLE const e)
{
return WaitForSingleObject(e, 0) == WAIT_OBJECT_0;
}
void SomeFunction()
{
HANDLE const e1 = CreateEvent(NULL, FALSE, FALSE, NULL); // not signaled
HANDLE const e2 = CreateEvent(NULL, FALSE, FALSE, NULL); // not signaled
HANDLE const e3 = CreateEvent(NULL, FALSE, FALSE, NULL); // not signaled
// let f() be a function that creates the object behind IAudioClient
// with AUDCLNT_SHAREMODE_EXCLUSIVE and AUDCLNT_STREAMFLAGS_EVENTCALLBACK
// but does not call IAudioClient::SetEventHandle
IAudioClient * const a = f(); // assume success
a->SetEventHandle(e1); // initial call, returns S_OK
assert(!Signaled(e1)); // true
a->SetEventHandle(e2); // subsequent call, returns S_OK
assert(!Signaled(e1)); // true
assert(!Signaled(e2)); // true
a->SetEventHandle(e3); // subsequent call, returns S_OK
assert(!Signaled(e1)); // true
assert(!Signaled(e2)); // true
assert(!Signaled(e3)); // true
a->Start(); // returns S_OK
assert(!Signaled(e1)); // true, as I expected
assert(!Signaled(e2)); // false!!!
assert(Signaled(e3)); // may be true or false, that's OK
}
К моему удивлению, e2 тоже сигнализируется. Почему?
В документации не говорится, что IAudioClient :: SetEventHandle может быть вызван только один раз, а затем никогда.
Если он может быть вызван снова с другим дескриптором события, чем текущий, я бы ожидал, что текущий будет просто заменен новым. Но кажется, что IAudioClient каким-то образом сохраняет оба дескриптора события, а затем сигнализирует обоим при Start (). Насколько я понимаю WASAPI и его механизм обратного вызова, это не имеет смысла.
Или у IAudioClient есть список последних двух дескрипторов событий? Или это ошибка в IAudioClient? Или документация неполная?
Помощь очень ценится. Ларри Остерман, если вам случится прочитать это, вы можете объяснить?