mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-28 09:55:29 +03:00
Make Applet accesses to the data queues lock
Avoids potential races when the guest access the same applet from more than one thread.
This commit is contained in:
parent
91b2c47991
commit
c15b3a8d40
@ -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<service::applet::CommonArguments>()};
|
||||
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<service::am::IStorage> data) {
|
||||
std::scoped_lock lock{inputDataMutex};
|
||||
normalInputData.emplace(std::move(data));
|
||||
}
|
||||
|
||||
|
@ -98,10 +98,12 @@ namespace skyline::applet {
|
||||
};
|
||||
static_assert(sizeof(ControllerSupportResultInfo) == 0xC);
|
||||
|
||||
std::mutex inputDataMutex;
|
||||
std::queue<std::shared_ptr<service::am::IStorage>> normalInputData;
|
||||
|
||||
template<typename T>
|
||||
T PopNormalInput() {
|
||||
std::scoped_lock lock{inputDataMutex};
|
||||
auto data{normalInputData.front()->GetSpan().as<T>()};
|
||||
normalInputData.pop();
|
||||
return static_cast<T>(data);
|
||||
|
@ -13,16 +13,19 @@ namespace skyline::service::am {
|
||||
IApplet::~IApplet() = default;
|
||||
|
||||
void IApplet::PushNormalDataAndSignal(std::shared_ptr<IStorage> data) {
|
||||
std::scoped_lock lock{outputDataMutex};
|
||||
normalOutputData.emplace(std::move(data));
|
||||
onNormalDataPushFromApplet->Signal();
|
||||
}
|
||||
|
||||
void IApplet::PushInteractiveDataAndSignal(std::shared_ptr<IStorage> data) {
|
||||
std::scoped_lock lock{interactiveOutputDataMutex};
|
||||
interactiveOutputData.emplace(std::move(data));
|
||||
onInteractiveDataPushFromApplet->Signal();
|
||||
}
|
||||
|
||||
std::shared_ptr<IStorage> IApplet::PopNormalAndClear() {
|
||||
std::scoped_lock lock{outputDataMutex};
|
||||
if (normalOutputData.empty())
|
||||
return {};
|
||||
std::shared_ptr<IStorage> data(normalOutputData.front());
|
||||
@ -32,6 +35,7 @@ namespace skyline::service::am {
|
||||
}
|
||||
|
||||
std::shared_ptr<IStorage> IApplet::PopInteractiveAndClear() {
|
||||
std::scoped_lock lock{interactiveOutputDataMutex};
|
||||
if (interactiveOutputData.empty())
|
||||
return {};
|
||||
std::shared_ptr<IStorage> data(interactiveOutputData.front());
|
||||
|
@ -17,11 +17,13 @@ namespace skyline::service::am {
|
||||
private:
|
||||
std::shared_ptr<kernel::type::KEvent> onNormalDataPushFromApplet;
|
||||
std::shared_ptr<kernel::type::KEvent> onInteractiveDataPushFromApplet;
|
||||
std::mutex outputDataMutex;
|
||||
std::queue<std::shared_ptr<IStorage>> normalOutputData; //!< Stores data sent by the applet so the guest can read it when it needs to
|
||||
std::mutex interactiveOutputDataMutex;
|
||||
std::queue<std::shared_ptr<IStorage>> interactiveOutputData; //!< Stores interactive data sent by the applet so the guest can read it when it needs to
|
||||
|
||||
protected:
|
||||
std::shared_ptr<kernel::type::KEvent> onAppletStateChanged;
|
||||
std::queue<std::shared_ptr<IStorage>> normalOutputData; //!< Stores data sent by the applet so the guest can read it when it needs to
|
||||
std::queue<std::shared_ptr<IStorage>> 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
|
||||
|
Loading…
Reference in New Issue
Block a user