#audio #windows-10
#Аудио #windows-10
Вопрос:
Вот несколько упрощенных примеров кода, объясняющих мой вопрос:
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 каким-то образом сохраняет оба дескриптора событий, а затем сигнализирует оба при запуске (). Насколько я понимаю WASAPI и его механизм обратного вызова событий, это не имеет смысла.
Или у IAudioClient есть список двух последних дескрипторов событий? Или это ошибка в IAudioClient? Или документация неполная?
Помощь очень ценится. Ларри Остерман, если ты случайно прочитаешь это, можешь объяснить?
Комментарии:
1. Довольно сомнительно, что кто-либо когда-либо замечал такое поведение. В документах также не говорится, что он забудет о ранее зарегистрированном дескрипторе, и для этого не зарезервирован код ошибки. Вам также нужно будет утверждать, что e2 сигнализируется, чтобы заключить, что список сохраняется.
2. @HansPassant Странная функция, интересно, почему они беспокоились. Я, конечно, не хотел бы полагаться на это.
3. @HansPassant Да, e2 тоже сигнализируется.
4. Выполнение дополнительной работы по ведению списка — это особенность, а не ошибка.
5. @HansPassant Хорошо, я согласен, но откуда мне знать об этой функции? Я ничего не могу найти об этом в документах. Поэтому я думаю, разумно предположить, что функция с именем setSomething() заменяет то, что установлено в данный момент, а не добавляет к нему. И в документах говорится, что «дескриптор события сигнализируется», а не «дескрипторы событий сигнализируются».