diff --git a/app/src/main/cpp/skyline/applet/controller_applet.cpp b/app/src/main/cpp/skyline/applet/controller_applet.cpp index c39ab51a..ee9865f5 100644 --- a/app/src/main/cpp/skyline/applet/controller_applet.cpp +++ b/app/src/main/cpp/skyline/applet/controller_applet.cpp @@ -21,12 +21,12 @@ namespace skyline::applet { // Generic macro due to both versions of arguments sharing the same fields but having different layouts auto handle{[&](auto controllerSupportModeArg) { Logger::InfoNoPrefix("Controller Support: " - "Player Count: {} - {}, " - "Take Over Connection: {}, Left Justify: {}, Dual Joy-Con Allowed: {}, Single Mode Enabled: {}, " - "Identification Color Enabled: {}, Explain Text Enabled: {}", - controllerSupportModeArg.playerCountMin, controllerSupportModeArg.playerCountMax, - controllerSupportModeArg.enableTakeOverConnection, controllerSupportModeArg.enableLeftJustify, controllerSupportModeArg.enablePermitJoyDual, controllerSupportModeArg.enableSingleMode, - controllerSupportModeArg.enableIdentificationColor, controllerSupportModeArg.enableExplainText); + "Player Count: {} - {}, " + "Take Over Connection: {}, Left Justify: {}, Dual Joy-Con Allowed: {}, Single Mode Enabled: {}, " + "Identification Color Enabled: {}, Explain Text Enabled: {}", + controllerSupportModeArg.playerCountMin, controllerSupportModeArg.playerCountMax, + controllerSupportModeArg.enableTakeOverConnection, controllerSupportModeArg.enableLeftJustify, controllerSupportModeArg.enablePermitJoyDual, controllerSupportModeArg.enableSingleMode, + controllerSupportModeArg.enableIdentificationColor, controllerSupportModeArg.enableExplainText); // Here is where we would trigger the applet UI @@ -62,6 +62,7 @@ namespace skyline::applet { break; } } + Result ControllerApplet::Start() { auto commonArg{PopNormalInput()}; ControllerAppletVersion appletVersion{commonArg.apiVersion}; @@ -81,6 +82,7 @@ namespace skyline::applet { } } + std::scoped_lock lock{inputDataMutex}; switch (argPrivate.mode) { case ControllerSupportMode::ShowControllerSupport: HandleShowControllerSupport(argPrivate.styleSet, appletVersion, normalInputData.front()->GetSpan()); @@ -105,6 +107,7 @@ namespace skyline::applet { } void ControllerApplet::PushNormalDataToApplet(std::shared_ptr data) { + std::scoped_lock lock{inputDataMutex}; normalInputData.emplace(std::move(data)); } diff --git a/app/src/main/cpp/skyline/applet/controller_applet.h b/app/src/main/cpp/skyline/applet/controller_applet.h index 226332d2..208a180e 100644 --- a/app/src/main/cpp/skyline/applet/controller_applet.h +++ b/app/src/main/cpp/skyline/applet/controller_applet.h @@ -98,10 +98,12 @@ namespace skyline::applet { }; static_assert(sizeof(ControllerSupportResultInfo) == 0xC); + std::mutex inputDataMutex; std::queue> normalInputData; template T PopNormalInput() { + std::scoped_lock lock{inputDataMutex}; auto data{normalInputData.front()->GetSpan().as()}; normalInputData.pop(); return static_cast(data); diff --git a/app/src/main/cpp/skyline/services/am/applet/IApplet.cpp b/app/src/main/cpp/skyline/services/am/applet/IApplet.cpp index ad8a3476..0ea11e61 100644 --- a/app/src/main/cpp/skyline/services/am/applet/IApplet.cpp +++ b/app/src/main/cpp/skyline/services/am/applet/IApplet.cpp @@ -13,16 +13,19 @@ namespace skyline::service::am { IApplet::~IApplet() = default; void IApplet::PushNormalDataAndSignal(std::shared_ptr data) { + std::scoped_lock lock{outputDataMutex}; normalOutputData.emplace(std::move(data)); onNormalDataPushFromApplet->Signal(); } void IApplet::PushInteractiveDataAndSignal(std::shared_ptr data) { + std::scoped_lock lock{interactiveOutputDataMutex}; interactiveOutputData.emplace(std::move(data)); onInteractiveDataPushFromApplet->Signal(); } std::shared_ptr IApplet::PopNormalAndClear() { + std::scoped_lock lock{outputDataMutex}; if (normalOutputData.empty()) return {}; std::shared_ptr data(normalOutputData.front()); @@ -32,6 +35,7 @@ namespace skyline::service::am { } std::shared_ptr IApplet::PopInteractiveAndClear() { + std::scoped_lock lock{interactiveOutputDataMutex}; if (interactiveOutputData.empty()) return {}; std::shared_ptr data(interactiveOutputData.front()); diff --git a/app/src/main/cpp/skyline/services/am/applet/IApplet.h b/app/src/main/cpp/skyline/services/am/applet/IApplet.h index 5d285f1e..fbe80e56 100644 --- a/app/src/main/cpp/skyline/services/am/applet/IApplet.h +++ b/app/src/main/cpp/skyline/services/am/applet/IApplet.h @@ -17,11 +17,13 @@ namespace skyline::service::am { private: std::shared_ptr onNormalDataPushFromApplet; std::shared_ptr onInteractiveDataPushFromApplet; + std::mutex outputDataMutex; + std::queue> normalOutputData; //!< Stores data sent by the applet so the guest can read it when it needs to + std::mutex interactiveOutputDataMutex; + std::queue> interactiveOutputData; //!< Stores interactive data sent by the applet so the guest can read it when it needs to protected: std::shared_ptr onAppletStateChanged; - std::queue> normalOutputData; //!< Stores data sent by the applet so the guest can read it when it needs to - std::queue> interactiveOutputData; //!< Stores interactive data sent by the applet so the guest can read it when it needs to /** * @brief Utility to send data to the guest and trigger the onNormalDataPushFromApplet event