Может ли IAudioClient::SetEventHandle вызываться только ровно один раз?

#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() заменяет то, что установлено в данный момент, а не добавляет к нему. И в документах говорится, что «дескриптор события сигнализируется», а не «дескрипторы событий сигнализируются».