diff --git a/src/back/backlasses.cpp b/src/back/backlasses.cpp index a0f0e06..517e10d 100644 --- a/src/back/backlasses.cpp +++ b/src/back/backlasses.cpp @@ -45,15 +45,20 @@ HRESULT EndpointNewSessionCallback::OnSessionCreated(IAudioSessionControl *NewSe //ISimmpleAudioVolume* sessionVolume; if (FAILED(NewSession->QueryInterface(__uuidof(IAudioSessionControl2), (void**)&sessionControl))) { log_wdebugcpp(L"no nueva sesion......"); }; if (sessionControl) { - sessionControl->AddRef(); - //sessionControl->QueryInterface(__uuidof(ISimpleAudioVolume), (void**)&sessionVolume); Session* newSession = new Session(this->eph->getEndpoint(), sessionControl); - eph->addSessionSendFront(newSession); + + SessionThreadParams tp = { .eph = this->eph, .session = newSession, .isDelete = false }; + std::thread sessionThread(EndpointNewSessionCallback::createSessionThread, tp); + sessionThread.detach(); } return S_OK; } +void EndpointNewSessionCallback::createSessionThread(SessionThreadParams params) { + params.eph->addSessionSendFront(params.session); +} + EndpointVolumeCallback::EndpointVolumeCallback(Endpoint* ep){ this->ep = ep; } @@ -224,6 +229,7 @@ HRESULT EndpointSituationCallback::OnDeviceStateChanged(LPCWSTR pwstrDeviceId, D } HRESULT EndpointSituationCallback::OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key) { + //TODO: New thread + Mutex os->updateEndpointInfo(std::wstring(pwstrDeviceId)); return S_OK; } @@ -236,7 +242,6 @@ Endpoint::Endpoint(IMMDevice* ep, IPolicyConfig7* policyConfig, uint64_t idx){ * It can't multiflag, it's that stupid. MS momento. * Only shows most relevant flag according to MS, i.e. 0110 sends 0010 */ - //todo: preguntitas owindows dword no es uint32_t even tho mingw mingas if(FAILED(endpoint->GetState(&this->endpointState))) {exit(-2);}; if(this->endpointState == EndpointState::ENDPOINT_ACTIVE) { @@ -288,7 +293,6 @@ void Endpoint::activateEndpointSessions() { log_debugcpp("Couldn't open session manager2, huh"); return; } - IAudioSessionEnumerator* sessionEnumerator = nullptr; if (FAILED(sessionManager->GetSessionEnumerator(&sessionEnumerator))) { log_wdebugcpp(L"sesEnumeratorBros..."); return; } @@ -488,7 +492,9 @@ std::vector Endpoint::getSessions() { } size_t Endpoint::getSessionCount() { - return endpointSessions.size(); + size_t sessionCount; + sessionCount = endpointSessions.size(); + return sessionCount; } void Endpoint::registerNewSessionNotification(EndpointNewSessionCallback* ensc){ @@ -507,6 +513,7 @@ void Endpoint::deleteSessions() { } Endpoint::~Endpoint(){ + //EPs are never deleted. log_wdebugcpp(L"murio endpoint-san uwu"); properties->Release(); endpointVolume->Release(); diff --git a/src/back/backlasses.h b/src/back/backlasses.h index 071e0e1..511774b 100644 --- a/src/back/backlasses.h +++ b/src/back/backlasses.h @@ -82,6 +82,7 @@ class Endpoint { void unregisterNewSessionNotification(EndpointNewSessionCallback* ensc); void deleteSessions(); void activateEndpointSessions(); + std::mutex endpointSessionsMutex; ~Endpoint(); private: @@ -185,16 +186,26 @@ class Overseer { }; class EndpointNewSessionCallback : public IAudioSessionNotification { + private: + struct SessionThreadParams; + public: EndpointNewSessionCallback(EndpointHandler *eph); ULONG AddRef(); ULONG Release(); HRESULT QueryInterface(REFIID riid, VOID **ppvInterface); HRESULT OnSessionCreated(IAudioSessionControl *NewSession); + static void createSessionThread(SessionThreadParams params); private: ULONG ref = 1; EndpointHandler *eph; + + struct SessionThreadParams { + EndpointHandler *eph; + Session *session; + bool isDelete; + }; }; namespace Environment { diff --git a/src/back/backsessionclasses.cpp b/src/back/backsessionclasses.cpp index aafe147..f98369f 100644 --- a/src/back/backsessionclasses.cpp +++ b/src/back/backsessionclasses.cpp @@ -37,6 +37,8 @@ HRESULT SessionStateCallback::QueryInterface(REFIID riid, VOID **ppvInterface) { } HRESULT SessionStateCallback::OnDisplayNameChanged(LPCWSTR NewDisplayName, LPCGUID EventContext) { + //TODO: Preguntar + while(sh->getVolumeInfo()->isNameChanged == true); sh->setName(std::wstring(NewDisplayName)); sh->getVolumeInfo()->isNameChanged = true; return S_OK; diff --git a/src/cont/contclasses.cpp b/src/cont/contclasses.cpp index e9561f0..ad85647 100644 --- a/src/cont/contclasses.cpp +++ b/src/cont/contclasses.cpp @@ -191,10 +191,15 @@ Endpoint* EndpointHandler::getEndpoint() { } void EndpointHandler::addSessionSendFront(Session* session) { - ep->addSession(session); - + if(!ep->endpointSessionsMutex.try_lock()) return; + + this->ep->addSession(session); SessionHandler* sessionHandler = new SessionHandler(this, session, (getSessionCount() - 1)); + ep->endpointSessionsMutex.unlock(); + + sessionHandlersMutex.lock(); sessionHandlers.push_back(sessionHandler); + sessionHandlersMutex.unlock(); this->addSessionWidget(sessionHandler); } @@ -218,14 +223,24 @@ void EndpointHandler::deleteSessions() { void EndpointHandler::createSessionHandlers() { ep->activateEndpointSessions(); - ensc = new EndpointNewSessionCallback(this); - ep->registerNewSessionNotification(ensc); if (this->flow == Flows::FLOW_PLAYBACK) { for (int i = 0; i < this->getSessionCount(); i++) { SessionHandler* sessionHandler = new SessionHandler(this, this->getSessions().at(i),i); sessionHandlers.push_back(sessionHandler); } - } + } + ensc = new EndpointNewSessionCallback(this); + ep->registerNewSessionNotification(ensc); +} + +void EndpointHandler::lockSessionCollections() { + this->sessionHandlersMutex.lock(); + this->ep->endpointSessionsMutex.lock(); +} + +void EndpointHandler::unlockSessionCollections() { + this->sessionHandlersMutex.unlock(); + this->ep->endpointSessionsMutex.unlock(); } EndpointHandler::~EndpointHandler() { @@ -386,6 +401,7 @@ void OverseerHandler::updateFrontEndpointName(Endpoint* ep) { } void OverseerHandler::reviseEndpointShowing(std::wstring endpointId, EndpointState state) { + //TODO: Race condition!!!!! std::vector allHandlers; allHandlers.insert(allHandlers.end(), this->captureEndpointHandlers.begin(), this->captureEndpointHandlers.end()); allHandlers.insert(allHandlers.end(), this->playbackEndpointHandlers.begin(), this->playbackEndpointHandlers.end()); diff --git a/src/cont/contclasses.h b/src/cont/contclasses.h index ac4ecdc..9d43088 100644 --- a/src/cont/contclasses.h +++ b/src/cont/contclasses.h @@ -76,6 +76,9 @@ public: void removeSessionFromFront(SessionHandler* sh); void deleteSessions(); void createSessionHandlers(); + std::mutex sessionHandlersMutex; + void lockSessionCollections(); + void unlockSessionCollections(); ~EndpointHandler(); private: diff --git a/src/cont/contsessionclasses.cpp b/src/cont/contsessionclasses.cpp index b63631e..fd53e62 100644 --- a/src/cont/contsessionclasses.cpp +++ b/src/cont/contsessionclasses.cpp @@ -5,7 +5,7 @@ SessionHandler::SessionHandler(EndpointHandler* eph, Session* session, size_t id this->eph = eph; this->idx = idx; this->session = session; - + this->svi.mainVolume = session->getVolume(AudioChannel::CHANNEL_MAIN); this->svi.muted = session->getMute(); this->svi.caller = osh->getGuid(); diff --git a/src/debug.h b/src/debug.h index d4b9195..61855c1 100644 --- a/src/debug.h +++ b/src/debug.h @@ -58,7 +58,7 @@ std::bitset varToBitset(T info) { OutputDebugStringW(std::wstring(L"[DEBUG] (" + std::wstring(WFILE) + L":" + std::to_wstring(__LINE__) + L"): " + std::wstring(str) +L"\n").c_str()); \ } while (0) -#endif +#endif //_WIN32 #define log_to_file(fmt, cnt...) do { \ if(writable) fprintf_s(fileLog, fmt,##cnt); \ @@ -76,7 +76,7 @@ std::bitset varToBitset(T info) { #define initialize_file_log() false #define close_file_log_buffer() #define PIPE_NAME "Mixerq" -#endif +#endif //DEBUG /* Here as a quick reference, in case smthn similar is needed again */ /* typedef void (EndpointWidget::*epwMuteFunc)(bool muted); */ diff --git a/src/global.h b/src/global.h index ba5678b..88f2dae 100644 --- a/src/global.h +++ b/src/global.h @@ -11,6 +11,7 @@ #include #include #include +#include #include "debug.h" //#include "settings.h" diff --git a/src/qt/qtclasses.cpp b/src/qt/qtclasses.cpp index 376cdcd..07adb81 100644 --- a/src/qt/qtclasses.cpp +++ b/src/qt/qtclasses.cpp @@ -750,7 +750,9 @@ EndpointWidget::~EndpointWidget() { timer->stop(); delete timer; this->eph->setFrontVisibilityInfo(EndpointState::ENDPOINT_ALL, INT_MAX); + this->eph->lockSessionCollections(); this->eph->deleteSessions(); + this->eph->unlockSessionCollections(); for(auto sw : sessionWidgets) { delete sw; } diff --git a/src/qt/qtclasses.h b/src/qt/qtclasses.h index 1ca937d..6d1ec61 100644 --- a/src/qt/qtclasses.h +++ b/src/qt/qtclasses.h @@ -203,7 +203,7 @@ private slots: private: //std::vector *ephs; - bool eventFilter(QObject *object, QEvent *event); + bool eventFilter(QObject *object, QEvent *event) override; void flushRoleChanges(); void changeFrontDefaults(Roles role, EndpointWidget* newDef, EndpointWidget* oldDef);