mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-05 11:45:10 +01: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
|
// Generic macro due to both versions of arguments sharing the same fields but having different layouts
|
||||||
auto handle{[&](auto controllerSupportModeArg) {
|
auto handle{[&](auto controllerSupportModeArg) {
|
||||||
Logger::InfoNoPrefix("Controller Support: "
|
Logger::InfoNoPrefix("Controller Support: "
|
||||||
"Player Count: {} - {}, "
|
"Player Count: {} - {}, "
|
||||||
"Take Over Connection: {}, Left Justify: {}, Dual Joy-Con Allowed: {}, Single Mode Enabled: {}, "
|
"Take Over Connection: {}, Left Justify: {}, Dual Joy-Con Allowed: {}, Single Mode Enabled: {}, "
|
||||||
"Identification Color Enabled: {}, Explain Text Enabled: {}",
|
"Identification Color Enabled: {}, Explain Text Enabled: {}",
|
||||||
controllerSupportModeArg.playerCountMin, controllerSupportModeArg.playerCountMax,
|
controllerSupportModeArg.playerCountMin, controllerSupportModeArg.playerCountMax,
|
||||||
controllerSupportModeArg.enableTakeOverConnection, controllerSupportModeArg.enableLeftJustify, controllerSupportModeArg.enablePermitJoyDual, controllerSupportModeArg.enableSingleMode,
|
controllerSupportModeArg.enableTakeOverConnection, controllerSupportModeArg.enableLeftJustify, controllerSupportModeArg.enablePermitJoyDual, controllerSupportModeArg.enableSingleMode,
|
||||||
controllerSupportModeArg.enableIdentificationColor, controllerSupportModeArg.enableExplainText);
|
controllerSupportModeArg.enableIdentificationColor, controllerSupportModeArg.enableExplainText);
|
||||||
|
|
||||||
// Here is where we would trigger the applet UI
|
// Here is where we would trigger the applet UI
|
||||||
|
|
||||||
@ -62,6 +62,7 @@ namespace skyline::applet {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ControllerApplet::Start() {
|
Result ControllerApplet::Start() {
|
||||||
auto commonArg{PopNormalInput<service::applet::CommonArguments>()};
|
auto commonArg{PopNormalInput<service::applet::CommonArguments>()};
|
||||||
ControllerAppletVersion appletVersion{commonArg.apiVersion};
|
ControllerAppletVersion appletVersion{commonArg.apiVersion};
|
||||||
@ -81,6 +82,7 @@ namespace skyline::applet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::scoped_lock lock{inputDataMutex};
|
||||||
switch (argPrivate.mode) {
|
switch (argPrivate.mode) {
|
||||||
case ControllerSupportMode::ShowControllerSupport:
|
case ControllerSupportMode::ShowControllerSupport:
|
||||||
HandleShowControllerSupport(argPrivate.styleSet, appletVersion, normalInputData.front()->GetSpan());
|
HandleShowControllerSupport(argPrivate.styleSet, appletVersion, normalInputData.front()->GetSpan());
|
||||||
@ -105,6 +107,7 @@ namespace skyline::applet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ControllerApplet::PushNormalDataToApplet(std::shared_ptr<service::am::IStorage> data) {
|
void ControllerApplet::PushNormalDataToApplet(std::shared_ptr<service::am::IStorage> data) {
|
||||||
|
std::scoped_lock lock{inputDataMutex};
|
||||||
normalInputData.emplace(std::move(data));
|
normalInputData.emplace(std::move(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,10 +98,12 @@ namespace skyline::applet {
|
|||||||
};
|
};
|
||||||
static_assert(sizeof(ControllerSupportResultInfo) == 0xC);
|
static_assert(sizeof(ControllerSupportResultInfo) == 0xC);
|
||||||
|
|
||||||
|
std::mutex inputDataMutex;
|
||||||
std::queue<std::shared_ptr<service::am::IStorage>> normalInputData;
|
std::queue<std::shared_ptr<service::am::IStorage>> normalInputData;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T PopNormalInput() {
|
T PopNormalInput() {
|
||||||
|
std::scoped_lock lock{inputDataMutex};
|
||||||
auto data{normalInputData.front()->GetSpan().as<T>()};
|
auto data{normalInputData.front()->GetSpan().as<T>()};
|
||||||
normalInputData.pop();
|
normalInputData.pop();
|
||||||
return static_cast<T>(data);
|
return static_cast<T>(data);
|
||||||
|
@ -13,16 +13,19 @@ namespace skyline::service::am {
|
|||||||
IApplet::~IApplet() = default;
|
IApplet::~IApplet() = default;
|
||||||
|
|
||||||
void IApplet::PushNormalDataAndSignal(std::shared_ptr<IStorage> data) {
|
void IApplet::PushNormalDataAndSignal(std::shared_ptr<IStorage> data) {
|
||||||
|
std::scoped_lock lock{outputDataMutex};
|
||||||
normalOutputData.emplace(std::move(data));
|
normalOutputData.emplace(std::move(data));
|
||||||
onNormalDataPushFromApplet->Signal();
|
onNormalDataPushFromApplet->Signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IApplet::PushInteractiveDataAndSignal(std::shared_ptr<IStorage> data) {
|
void IApplet::PushInteractiveDataAndSignal(std::shared_ptr<IStorage> data) {
|
||||||
|
std::scoped_lock lock{interactiveOutputDataMutex};
|
||||||
interactiveOutputData.emplace(std::move(data));
|
interactiveOutputData.emplace(std::move(data));
|
||||||
onInteractiveDataPushFromApplet->Signal();
|
onInteractiveDataPushFromApplet->Signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IStorage> IApplet::PopNormalAndClear() {
|
std::shared_ptr<IStorage> IApplet::PopNormalAndClear() {
|
||||||
|
std::scoped_lock lock{outputDataMutex};
|
||||||
if (normalOutputData.empty())
|
if (normalOutputData.empty())
|
||||||
return {};
|
return {};
|
||||||
std::shared_ptr<IStorage> data(normalOutputData.front());
|
std::shared_ptr<IStorage> data(normalOutputData.front());
|
||||||
@ -32,6 +35,7 @@ namespace skyline::service::am {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IStorage> IApplet::PopInteractiveAndClear() {
|
std::shared_ptr<IStorage> IApplet::PopInteractiveAndClear() {
|
||||||
|
std::scoped_lock lock{interactiveOutputDataMutex};
|
||||||
if (interactiveOutputData.empty())
|
if (interactiveOutputData.empty())
|
||||||
return {};
|
return {};
|
||||||
std::shared_ptr<IStorage> data(interactiveOutputData.front());
|
std::shared_ptr<IStorage> data(interactiveOutputData.front());
|
||||||
|
@ -17,11 +17,13 @@ namespace skyline::service::am {
|
|||||||
private:
|
private:
|
||||||
std::shared_ptr<kernel::type::KEvent> onNormalDataPushFromApplet;
|
std::shared_ptr<kernel::type::KEvent> onNormalDataPushFromApplet;
|
||||||
std::shared_ptr<kernel::type::KEvent> onInteractiveDataPushFromApplet;
|
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:
|
protected:
|
||||||
std::shared_ptr<kernel::type::KEvent> onAppletStateChanged;
|
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
|
* @brief Utility to send data to the guest and trigger the onNormalDataPushFromApplet event
|
||||||
|
Loading…
Reference in New Issue
Block a user