summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2020-12-29 03:23:42 +0100
committerbunnei <bunneidev@gmail.com>2020-12-29 06:33:34 +0100
commit7d77a3f88f7a1e68d9846ca7c69cce051d1a33d2 (patch)
treebe882bb9b5d144861673178a1fdaad9a19504c5a /src
parentaudio_core: stream: Ensure buffer is valid before release. (diff)
downloadyuzu-7d77a3f88f7a1e68d9846ca7c69cce051d1a33d2.tar
yuzu-7d77a3f88f7a1e68d9846ca7c69cce051d1a33d2.tar.gz
yuzu-7d77a3f88f7a1e68d9846ca7c69cce051d1a33d2.tar.bz2
yuzu-7d77a3f88f7a1e68d9846ca7c69cce051d1a33d2.tar.lz
yuzu-7d77a3f88f7a1e68d9846ca7c69cce051d1a33d2.tar.xz
yuzu-7d77a3f88f7a1e68d9846ca7c69cce051d1a33d2.tar.zst
yuzu-7d77a3f88f7a1e68d9846ca7c69cce051d1a33d2.zip
Diffstat (limited to '')
-rw-r--r--src/audio_core/audio_renderer.cpp13
-rw-r--r--src/audio_core/audio_renderer.h8
-rw-r--r--src/core/hle/service/audio/audout_u.cpp6
-rw-r--r--src/core/hle/service/audio/audren_u.cpp14
-rw-r--r--src/core/hle/service/hid/hid.cpp2
-rw-r--r--src/core/hle/service/service.cpp22
-rw-r--r--src/core/hle/service/service.h16
7 files changed, 41 insertions, 40 deletions
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp
index 179560cd7..d2ce8c814 100644
--- a/src/audio_core/audio_renderer.cpp
+++ b/src/audio_core/audio_renderer.cpp
@@ -11,7 +11,6 @@
#include "audio_core/info_updater.h"
#include "audio_core/voice_context.h"
#include "common/logging/log.h"
-#include "core/hle/kernel/writable_event.h"
#include "core/memory.h"
#include "core/settings.h"
@@ -71,10 +70,9 @@ namespace {
namespace AudioCore {
AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_,
AudioCommon::AudioRendererParameter params,
- std::shared_ptr<Kernel::WritableEvent> buffer_event_,
+ Stream::ReleaseCallback&& release_callback,
std::size_t instance_number)
- : worker_params{params}, buffer_event{buffer_event_},
- memory_pool_info(params.effect_count + params.voice_count * 4),
+ : worker_params{params}, memory_pool_info(params.effect_count + params.voice_count * 4),
voice_context(params.voice_count), effect_context(params.effect_count), mix_context(),
sink_context(params.sink_count), splitter_context(),
voices(params.voice_count), memory{memory_},
@@ -85,10 +83,9 @@ AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory
params.num_splitter_send_channels);
mix_context.Initialize(behavior_info, params.submix_count + 1, params.effect_count);
audio_out = std::make_unique<AudioCore::AudioOut>();
- stream =
- audio_out->OpenStream(core_timing, params.sample_rate, AudioCommon::STREAM_NUM_CHANNELS,
- fmt::format("AudioRenderer-Instance{}", instance_number),
- [=]() { buffer_event_->Signal(); });
+ stream = audio_out->OpenStream(
+ core_timing, params.sample_rate, AudioCommon::STREAM_NUM_CHANNELS,
+ fmt::format("AudioRenderer-Instance{}", instance_number), std::move(release_callback));
audio_out->StartStream(stream);
QueueMixedBuffer(0);
diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h
index 90f7eafa4..18567f618 100644
--- a/src/audio_core/audio_renderer.h
+++ b/src/audio_core/audio_renderer.h
@@ -27,10 +27,6 @@ namespace Core::Timing {
class CoreTiming;
}
-namespace Kernel {
-class WritableEvent;
-}
-
namespace Core::Memory {
class Memory;
}
@@ -44,8 +40,7 @@ class AudioRenderer {
public:
AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_,
AudioCommon::AudioRendererParameter params,
- std::shared_ptr<Kernel::WritableEvent> buffer_event_,
- std::size_t instance_number);
+ Stream::ReleaseCallback&& release_callback, std::size_t instance_number);
~AudioRenderer();
[[nodiscard]] ResultCode UpdateAudioRenderer(const std::vector<u8>& input_params,
@@ -61,7 +56,6 @@ private:
BehaviorInfo behavior_info{};
AudioCommon::AudioRendererParameter worker_params;
- std::shared_ptr<Kernel::WritableEvent> buffer_event;
std::vector<ServerMemoryPoolInfo> memory_pool_info;
VoiceContext voice_context;
EffectContext effect_context;
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 145f47ee2..0cd797109 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -70,8 +70,10 @@ public:
Kernel::WritableEvent::CreateEventPair(system.Kernel(), "IAudioOutBufferReleased");
stream = audio_core.OpenStream(system.CoreTiming(), audio_params.sample_rate,
- audio_params.channel_count, std::move(unique_name),
- [this] { buffer_event.writable->Signal(); });
+ audio_params.channel_count, std::move(unique_name), [this] {
+ const auto guard = LockService();
+ buffer_event.writable->Signal();
+ });
}
private:
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 6e7b7316c..c5c22d053 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -49,16 +49,16 @@ public:
system_event =
Kernel::WritableEvent::CreateEventPair(system.Kernel(), "IAudioRenderer:SystemEvent");
- renderer = std::make_unique<AudioCore::AudioRenderer>(system.CoreTiming(), system.Memory(),
- audren_params, system_event.writable,
- instance_number);
+ renderer = std::make_unique<AudioCore::AudioRenderer>(
+ system.CoreTiming(), system.Memory(), audren_params,
+ [this]() {
+ const auto guard = LockService();
+ system_event.writable->Signal();
+ },
+ instance_number);
}
private:
- void UpdateAudioCallback() {
- system_event.writable->Signal();
- }
-
void GetSampleRate(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_Audio, "called");
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index b3c7234e1..8d95f74e6 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -78,11 +78,13 @@ IAppletResource::IAppletResource(Core::System& system_)
pad_update_event = Core::Timing::CreateEvent(
"HID::UpdatePadCallback",
[this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
+ const auto guard = LockService();
UpdateControllers(user_data, ns_late);
});
motion_update_event = Core::Timing::CreateEvent(
"HID::MotionPadCallback",
[this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
+ const auto guard = LockService();
UpdateMotion(user_data, ns_late);
});
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index d55fba831..ff2a5b1db 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -95,9 +95,14 @@ ServiceFrameworkBase::ServiceFrameworkBase(Core::System& system_, const char* se
: system{system_}, service_name{service_name_}, max_sessions{max_sessions_},
handler_invoker{handler_invoker_} {}
-ServiceFrameworkBase::~ServiceFrameworkBase() = default;
+ServiceFrameworkBase::~ServiceFrameworkBase() {
+ // Wait for other threads to release access before destroying
+ const auto guard = LockService();
+}
void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager) {
+ const auto guard = LockService();
+
ASSERT(!port_installed);
auto port = service_manager.RegisterService(service_name, max_sessions).Unwrap();
@@ -106,6 +111,8 @@ void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager)
}
void ServiceFrameworkBase::InstallAsNamedPort(Kernel::KernelCore& kernel) {
+ const auto guard = LockService();
+
ASSERT(!port_installed);
auto [server_port, client_port] =
@@ -115,17 +122,6 @@ void ServiceFrameworkBase::InstallAsNamedPort(Kernel::KernelCore& kernel) {
port_installed = true;
}
-std::shared_ptr<Kernel::ClientPort> ServiceFrameworkBase::CreatePort(Kernel::KernelCore& kernel) {
- ASSERT(!port_installed);
-
- auto [server_port, client_port] =
- Kernel::ServerPort::CreatePortPair(kernel, max_sessions, service_name);
- auto port = MakeResult(std::move(server_port)).Unwrap();
- port->SetHleHandler(shared_from_this());
- port_installed = true;
- return client_port;
-}
-
void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n) {
handlers.reserve(handlers.size() + n);
for (std::size_t i = 0; i < n; ++i) {
@@ -164,6 +160,8 @@ void ServiceFrameworkBase::InvokeRequest(Kernel::HLERequestContext& ctx) {
}
ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& context) {
+ const auto guard = LockService();
+
switch (context.GetCommandType()) {
case IPC::CommandType::Close: {
IPC::ResponseBuilder rb{context, 2};
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index 62a182310..916445517 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -5,9 +5,11 @@
#pragma once
#include <cstddef>
+#include <mutex>
#include <string>
#include <boost/container/flat_map.hpp>
#include "common/common_types.h"
+#include "common/spin_lock.h"
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/kernel/object.h"
@@ -68,11 +70,9 @@ public:
void InstallAsService(SM::ServiceManager& service_manager);
/// Creates a port pair and registers it on the kernel's global port registry.
void InstallAsNamedPort(Kernel::KernelCore& kernel);
- /// Creates and returns an unregistered port for the service.
- std::shared_ptr<Kernel::ClientPort> CreatePort(Kernel::KernelCore& kernel);
-
+ /// Invokes a service request routine.
void InvokeRequest(Kernel::HLERequestContext& ctx);
-
+ /// Handles a synchronization request for the service.
ResultCode HandleSyncRequest(Kernel::HLERequestContext& context) override;
protected:
@@ -80,6 +80,11 @@ protected:
template <typename Self>
using HandlerFnP = void (Self::*)(Kernel::HLERequestContext&);
+ /// Used to gain exclusive access to the service members, e.g. from CoreTiming thread.
+ [[nodiscard]] std::scoped_lock<Common::SpinLock> LockService() {
+ return std::scoped_lock{lock_service};
+ }
+
/// System context that the service operates under.
Core::System& system;
@@ -115,6 +120,9 @@ private:
/// Function used to safely up-cast pointers to the derived class before invoking a handler.
InvokerFn* handler_invoker;
boost::container::flat_map<u32, FunctionInfoBase> handlers;
+
+ /// Used to gain exclusive access to the service members, e.g. from CoreTiming thread.
+ Common::SpinLock lock_service;
};
/**