diff options
| author | bunnei <bunneidev@gmail.com> | 2020-12-28 18:23:42 -0800 | 
|---|---|---|
| committer | bunnei <bunneidev@gmail.com> | 2020-12-28 21:33:34 -0800 | 
| commit | 7d77a3f88f7a1e68d9846ca7c69cce051d1a33d2 (patch) | |
| tree | be882bb9b5d144861673178a1fdaad9a19504c5a | |
| parent | c7a06908ae1a1c0893876800944e494a0fa03918 (diff) | |
hle: service: Acquire and release a lock on requests.
- This makes it such that we can safely access service members from CoreTiming thread.
| -rw-r--r-- | src/audio_core/audio_renderer.cpp | 13 | ||||
| -rw-r--r-- | src/audio_core/audio_renderer.h | 8 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audout_u.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audren_u.cpp | 14 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/service.cpp | 22 | ||||
| -rw-r--r-- | src/core/hle/service/service.h | 16 | 
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;  };  /** | 
