powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Народ, помогите, мозг уже сломал. WASAPI. C++.
3 сообщений из 3, страница 1 из 1
Народ, помогите, мозг уже сломал. WASAPI. C++.
    #39107373
Acute
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Итак, имеем код, который отслеживает события. IMMNotificationClient - вот он отслеживает.
Я также держу список объектов IAudioSessionControl. По событию вызываю метод Release(). Всё. Зависон. Всё, что нашёл, это китаец создаёт отдельный поток и отправляет циклу обработки сообщений этого потока сообщения. Но и он, как я понял, столкнулся с этой проблемой. Он вызывает Sleep(200). Костыль же.
Я считаю, правильное решение - это узнавать, находится ли поток в обработке события IMMNotificationClient. Если находимся - ждём. Как вышли - вызываем наш Release(). Как это сделать на практике?
Нашёл такую функцию: LeaveCriticalSectionWhenCallbackReturns. Но чот не врубаюсь как метод класса ей передать. И вообще правильно ли так будет.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
HRESULT STDMETHODCALLTYPE CMMNotificationClient::OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState)
{
	// Кандидат на место зачистки списка сессий.
	// На самом деле пишут, что нельзя ожидать синхронизации
	// Тут: https://msdn.microsoft.com/en-us/library/windows/desktop/dd371417.aspx
	// А китаец в программе Muter https://github.com/yxl/Firefox-Muter, модуле AudioVolume.cpp ждёт.
	// Также пишут: "The client should never release the final reference on an MMDevice API object during an event callback".
	// Но я пытаюсь удалить список объектов типа IAudioSessionControl. И всё равно виснет.
	// Нужно как-то определять в потоке обработки, что поток событий не находится тут.
	// Во, вот это я видел и потом забыл и искал: LeaveCriticalSectionWhenCallbackReturns function
	// https://msdn.microsoft.com/en-us/library/ms684171.aspx

	EnterCriticalSection(&mk_Critical); // Это не есть гуд, как я понимаю.
	PostThreadMessage(threadId, MSG_USER_DEVICE_STATE_CHANGE, 0, 0);
	LeaveCriticalSection(&mk_Critical);
	//LeaveCriticalSectionWhenCallbackReturns(CMMNotificationClient::OnDeviceStateChanged, )
	return S_OK;
}



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
DWORD WINAPI ThreadProc(_In_ LPVOID lpParameter)
{
	MSG msg;
	while (GetMessage(&msg, 0, 0, 0)) {
		switch (msg.message) {
		case MSG_USER_DEVICE_STATE_CHANGE: {
			Sleep(200); // Костыль. Убрать и будет зависон.
			// Тут мы где-то вызываем метод Release()
		}
		break;
		}
		DispatchMessage(&msg);
	}
	return 0;
}

...
Рейтинг: 0 / 0
Народ, помогите, мозг уже сломал. WASAPI. C++.
    #39110538
Acute
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всё, разобрался.
Проблема, естественно, в deadlock. В процессе обработки события IMMNotificationClient происходило событие из интерфейса IAudioSessionNotification. Нужно иметь ввиду, что при использовании критических секций любой вызов WASAPI вызовет deadlock, а не только вызов метода в пределах одного интерфейса.
Выход из положения нашёл в использовании Lock-free стека для Windows в качестве очереди сообщений потоку-обработчику.
...
Рейтинг: 0 / 0
Народ, помогите, мозг уже сломал. WASAPI. C++.
    #39110971
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Acute,

Я вообще не понимаю, что там у тебя и как, что это за IMMNotificationClient, но
PostThreadMessage()
обкладывать критическими секциями не нужно ни при каких обстоятельствах, тем более данных при этом не посылается.
При доступе к данным, которые посылаются, возможно, нужны секции или другая синхронизация, но не для посылки
сообщения.
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Народ, помогите, мозг уже сломал. WASAPI. C++.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]