kdeconnect-kde/plugins/systemvolume/systemvolumeplugin-win.h
Art Pinch 844d52f0a5 Fixed kdeconnectd deadlock on Windows caused by systemvolumeplugin
IAudioEndpointVolumeCallback::Release was called in callback functions of IMMNotificationClient (through the call to SystemvolumePlugin::sendSinkList), however https://docs.microsoft.com/en-us/windows/win32/api/mmdeviceapi/nn-mmdeviceapi-immnotificationclient points out that:
*To avoid dead locks, the client should never call IMMDeviceEnumerator::RegisterEndpointNotificationCallback or IMMDeviceEnumerator::UnregisterEndpointNotificationCallback in its implementation of IMMNotificationClient methods.
*The client should never release the final reference on an MMDevice API object during an event callback.

So I moved that part of code to another thread so it will successfully run after callback functions work out and call only if endpoint needs to be released (device was removed), so it won't spawn new thread for every generated event
2020-11-19 23:28:44 +03:00

49 lines
1.2 KiB
C++

/**
* SPDX-FileCopyrightText: 2018 Jun Bo Bi <jambonmcyeah@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#ifndef SYSTEMVOLUMEPLUGINWIN_H
#define SYSTEMVOLUMEPLUGINWIN_H
#include <QObject>
#include <QMap>
#include <core/kdeconnectplugin.h>
#include <Windows.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>
#ifdef __MINGW32__
#include <initguid.h>
#endif
#define PACKET_TYPE_SYSTEMVOLUME QStringLiteral("kdeconnect.systemvolume")
#define PACKET_TYPE_SYSTEMVOLUME_REQUEST QStringLiteral("kdeconnect.systemvolume.request")
class Q_DECL_EXPORT SystemvolumePlugin : public KdeConnectPlugin
{
Q_OBJECT
public:
explicit SystemvolumePlugin(QObject *parent, const QVariantList &args);
~SystemvolumePlugin();
bool receivePacket(const NetworkPacket& np) override;
void connected() override;
private:
class CMMNotificationClient;
class CAudioEndpointVolumeCallback;
bool valid;
IMMDeviceEnumerator* deviceEnumerator;
CMMNotificationClient* deviceCallback;
QMap<QString, QPair<IAudioEndpointVolume *, CAudioEndpointVolumeCallback *>> sinkList;
QMap<QString, QString> idToNameMap;
bool sendSinkList();
};
#endif // SYSTEMVOLUMEPLUGINWIN_H