service: Replace service event creation with ServiceContext::CreateEvent

The service context helps to manage all created events and allows us to close them upon destruction.
This commit is contained in:
Morph 2021-09-28 23:42:50 -04:00
parent 3a33519598
commit fadcee14f8
26 changed files with 367 additions and 271 deletions

View file

@ -16,9 +16,7 @@
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_readable_event.h"
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/kernel/k_writable_event.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/service/acc/profile_manager.h"
#include "core/hle/service/am/am.h"
@ -254,8 +252,9 @@ IDebugFunctions::IDebugFunctions(Core::System& system_)
IDebugFunctions::~IDebugFunctions() = default;
ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nvflinger_)
: ServiceFramework{system_, "ISelfController"}, nvflinger{nvflinger_},
launchable_event{system.Kernel()}, accumulated_suspended_tick_changed_event{system.Kernel()} {
: ServiceFramework{system_, "ISelfController"}, nvflinger{nvflinger_}, service_context{
system,
"ISelfController"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &ISelfController::Exit, "Exit"},
@ -311,9 +310,7 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv
RegisterHandlers(functions);
Kernel::KAutoObject::Create(std::addressof(launchable_event));
launchable_event.Initialize("ISelfController:LaunchableEvent");
launchable_event = service_context.CreateEvent("ISelfController:LaunchableEvent");
// This event is created by AM on the first time GetAccumulatedSuspendedTickChangedEvent() is
// called. Yuzu can just create it unconditionally, since it doesn't need to support multiple
@ -321,13 +318,15 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv
// suspended if the event has previously been created by a call to
// GetAccumulatedSuspendedTickChangedEvent.
Kernel::KAutoObject::Create(std::addressof(accumulated_suspended_tick_changed_event));
accumulated_suspended_tick_changed_event.Initialize(
"ISelfController:AccumulatedSuspendedTickChangedEvent");
accumulated_suspended_tick_changed_event.GetWritableEvent().Signal();
accumulated_suspended_tick_changed_event =
service_context.CreateEvent("ISelfController:AccumulatedSuspendedTickChangedEvent");
accumulated_suspended_tick_changed_event->GetWritableEvent().Signal();
}
ISelfController::~ISelfController() = default;
ISelfController::~ISelfController() {
service_context.CloseEvent(launchable_event);
service_context.CloseEvent(accumulated_suspended_tick_changed_event);
}
void ISelfController::Exit(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called");
@ -383,11 +382,11 @@ void ISelfController::LeaveFatalSection(Kernel::HLERequestContext& ctx) {
void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
launchable_event.GetWritableEvent().Signal();
launchable_event->GetWritableEvent().Signal();
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(launchable_event.GetReadableEvent());
rb.PushCopyObjects(launchable_event->GetReadableEvent());
}
void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) {
@ -566,7 +565,7 @@ void ISelfController::GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequest
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(accumulated_suspended_tick_changed_event.GetReadableEvent());
rb.PushCopyObjects(accumulated_suspended_tick_changed_event->GetReadableEvent());
}
void ISelfController::SetAlbumImageTakenNotificationEnabled(Kernel::HLERequestContext& ctx) {
@ -584,40 +583,39 @@ void ISelfController::SetAlbumImageTakenNotificationEnabled(Kernel::HLERequestCo
rb.Push(ResultSuccess);
}
AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel)
: on_new_message{kernel}, on_operation_mode_changed{kernel} {
Kernel::KAutoObject::Create(std::addressof(on_new_message));
Kernel::KAutoObject::Create(std::addressof(on_operation_mode_changed));
on_new_message.Initialize("AMMessageQueue:OnMessageReceived");
on_operation_mode_changed.Initialize("AMMessageQueue:OperationModeChanged");
AppletMessageQueue::AppletMessageQueue(Core::System& system)
: service_context{system, "AppletMessageQueue"} {
on_new_message = service_context.CreateEvent("AMMessageQueue:OnMessageReceived");
on_operation_mode_changed = service_context.CreateEvent("AMMessageQueue:OperationModeChanged");
}
AppletMessageQueue::~AppletMessageQueue() = default;
AppletMessageQueue::~AppletMessageQueue() {
service_context.CloseEvent(on_new_message);
service_context.CloseEvent(on_operation_mode_changed);
}
Kernel::KReadableEvent& AppletMessageQueue::GetMessageReceiveEvent() {
return on_new_message.GetReadableEvent();
return on_new_message->GetReadableEvent();
}
Kernel::KReadableEvent& AppletMessageQueue::GetOperationModeChangedEvent() {
return on_operation_mode_changed.GetReadableEvent();
return on_operation_mode_changed->GetReadableEvent();
}
void AppletMessageQueue::PushMessage(AppletMessage msg) {
messages.push(msg);
on_new_message.GetWritableEvent().Signal();
on_new_message->GetWritableEvent().Signal();
}
AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() {
if (messages.empty()) {
on_new_message.GetWritableEvent().Clear();
on_new_message->GetWritableEvent().Clear();
return AppletMessage::NoMessage;
}
auto msg = messages.front();
messages.pop();
if (messages.empty()) {
on_new_message.GetWritableEvent().Clear();
on_new_message->GetWritableEvent().Clear();
}
return msg;
}
@ -637,7 +635,7 @@ void AppletMessageQueue::FocusStateChanged() {
void AppletMessageQueue::OperationModeChanged() {
PushMessage(AppletMessage::OperationModeChanged);
PushMessage(AppletMessage::PerformanceModeChanged);
on_operation_mode_changed.GetWritableEvent().Signal();
on_operation_mode_changed->GetWritableEvent().Signal();
}
ICommonStateGetter::ICommonStateGetter(Core::System& system_,
@ -1272,10 +1270,8 @@ void ILibraryAppletCreator::CreateHandleStorage(Kernel::HLERequestContext& ctx)
}
IApplicationFunctions::IApplicationFunctions(Core::System& system_)
: ServiceFramework{system_, "IApplicationFunctions"}, gpu_error_detected_event{system.Kernel()},
friend_invitation_storage_channel_event{system.Kernel()},
notification_storage_channel_event{system.Kernel()}, health_warning_disappeared_system_event{
system.Kernel()} {
: ServiceFramework{system_, "IApplicationFunctions"}, service_context{system,
"IApplicationFunctions"} {
// clang-format off
static const FunctionInfo functions[] = {
{1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
@ -1343,21 +1339,22 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
RegisterHandlers(functions);
Kernel::KAutoObject::Create(std::addressof(gpu_error_detected_event));
Kernel::KAutoObject::Create(std::addressof(friend_invitation_storage_channel_event));
Kernel::KAutoObject::Create(std::addressof(notification_storage_channel_event));
Kernel::KAutoObject::Create(std::addressof(health_warning_disappeared_system_event));
gpu_error_detected_event.Initialize("IApplicationFunctions:GpuErrorDetectedSystemEvent");
friend_invitation_storage_channel_event.Initialize(
"IApplicationFunctions:FriendInvitationStorageChannelEvent");
notification_storage_channel_event.Initialize(
"IApplicationFunctions:NotificationStorageChannelEvent");
health_warning_disappeared_system_event.Initialize(
"IApplicationFunctions:HealthWarningDisappearedSystemEvent");
gpu_error_detected_event =
service_context.CreateEvent("IApplicationFunctions:GpuErrorDetectedSystemEvent");
friend_invitation_storage_channel_event =
service_context.CreateEvent("IApplicationFunctions:FriendInvitationStorageChannelEvent");
notification_storage_channel_event =
service_context.CreateEvent("IApplicationFunctions:NotificationStorageChannelEvent");
health_warning_disappeared_system_event =
service_context.CreateEvent("IApplicationFunctions:HealthWarningDisappearedSystemEvent");
}
IApplicationFunctions::~IApplicationFunctions() = default;
IApplicationFunctions::~IApplicationFunctions() {
service_context.CloseEvent(gpu_error_detected_event);
service_context.CloseEvent(friend_invitation_storage_channel_event);
service_context.CloseEvent(notification_storage_channel_event);
service_context.CloseEvent(health_warning_disappeared_system_event);
}
void IApplicationFunctions::EnableApplicationCrashReport(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
@ -1751,7 +1748,7 @@ void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(Kernel::HLERequestCon
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(gpu_error_detected_event.GetReadableEvent());
rb.PushCopyObjects(gpu_error_detected_event->GetReadableEvent());
}
void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERequestContext& ctx) {
@ -1759,7 +1756,7 @@ void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERe
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(friend_invitation_storage_channel_event.GetReadableEvent());
rb.PushCopyObjects(friend_invitation_storage_channel_event->GetReadableEvent());
}
void IApplicationFunctions::TryPopFromFriendInvitationStorageChannel(
@ -1775,7 +1772,7 @@ void IApplicationFunctions::GetNotificationStorageChannelEvent(Kernel::HLEReques
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(notification_storage_channel_event.GetReadableEvent());
rb.PushCopyObjects(notification_storage_channel_event->GetReadableEvent());
}
void IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(Kernel::HLERequestContext& ctx) {
@ -1783,12 +1780,12 @@ void IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(Kernel::HLERe
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(health_warning_disappeared_system_event.GetReadableEvent());
rb.PushCopyObjects(health_warning_disappeared_system_event->GetReadableEvent());
}
void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger,
Core::System& system) {
auto message_queue = std::make_shared<AppletMessageQueue>(system.Kernel());
auto message_queue = std::make_shared<AppletMessageQueue>(system);
// Needed on game boot
message_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
@ -1801,8 +1798,8 @@ void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger
}
IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_)
: ServiceFramework{system_, "IHomeMenuFunctions"}, pop_from_general_channel_event{
system.Kernel()} {
: ServiceFramework{system_, "IHomeMenuFunctions"}, service_context{system,
"IHomeMenuFunctions"} {
// clang-format off
static const FunctionInfo functions[] = {
{10, &IHomeMenuFunctions::RequestToGetForeground, "RequestToGetForeground"},
@ -1823,11 +1820,13 @@ IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_)
RegisterHandlers(functions);
Kernel::KAutoObject::Create(std::addressof(pop_from_general_channel_event));
pop_from_general_channel_event.Initialize("IHomeMenuFunctions:PopFromGeneralChannelEvent");
pop_from_general_channel_event =
service_context.CreateEvent("IHomeMenuFunctions:PopFromGeneralChannelEvent");
}
IHomeMenuFunctions::~IHomeMenuFunctions() = default;
IHomeMenuFunctions::~IHomeMenuFunctions() {
service_context.CloseEvent(pop_from_general_channel_event);
}
void IHomeMenuFunctions::RequestToGetForeground(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
@ -1841,7 +1840,7 @@ void IHomeMenuFunctions::GetPopFromGeneralChannelEvent(Kernel::HLERequestContext
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(pop_from_general_channel_event.GetReadableEvent());
rb.PushCopyObjects(pop_from_general_channel_event->GetReadableEvent());
}
IGlobalStateController::IGlobalStateController(Core::System& system_)

View file

@ -8,7 +8,7 @@
#include <memory>
#include <queue>
#include "core/hle/kernel/k_event.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/service.h"
namespace Kernel {
@ -53,7 +53,7 @@ public:
PerformanceModeChanged = 31,
};
explicit AppletMessageQueue(Kernel::KernelCore& kernel);
explicit AppletMessageQueue(Core::System& system);
~AppletMessageQueue();
Kernel::KReadableEvent& GetMessageReceiveEvent();
@ -66,9 +66,12 @@ public:
void OperationModeChanged();
private:
KernelHelpers::ServiceContext service_context;
Kernel::KEvent* on_new_message;
Kernel::KEvent* on_operation_mode_changed;
std::queue<AppletMessage> messages;
Kernel::KEvent on_new_message;
Kernel::KEvent on_operation_mode_changed;
};
class IWindowController final : public ServiceFramework<IWindowController> {
@ -156,8 +159,11 @@ private:
};
NVFlinger::NVFlinger& nvflinger;
Kernel::KEvent launchable_event;
Kernel::KEvent accumulated_suspended_tick_changed_event;
KernelHelpers::ServiceContext service_context;
Kernel::KEvent* launchable_event;
Kernel::KEvent* accumulated_suspended_tick_changed_event;
u32 idle_time_detection_extension = 0;
u64 num_fatal_sections_entered = 0;
@ -298,13 +304,15 @@ private:
void GetNotificationStorageChannelEvent(Kernel::HLERequestContext& ctx);
void GetHealthWarningDisappearedSystemEvent(Kernel::HLERequestContext& ctx);
KernelHelpers::ServiceContext service_context;
bool launch_popped_application_specific = false;
bool launch_popped_account_preselect = false;
s32 previous_program_index{-1};
Kernel::KEvent gpu_error_detected_event;
Kernel::KEvent friend_invitation_storage_channel_event;
Kernel::KEvent notification_storage_channel_event;
Kernel::KEvent health_warning_disappeared_system_event;
Kernel::KEvent* gpu_error_detected_event;
Kernel::KEvent* friend_invitation_storage_channel_event;
Kernel::KEvent* notification_storage_channel_event;
Kernel::KEvent* health_warning_disappeared_system_event;
};
class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> {
@ -316,7 +324,9 @@ private:
void RequestToGetForeground(Kernel::HLERequestContext& ctx);
void GetPopFromGeneralChannelEvent(Kernel::HLERequestContext& ctx);
Kernel::KEvent pop_from_general_channel_event;
KernelHelpers::ServiceContext service_context;
Kernel::KEvent* pop_from_general_channel_event;
};
class IGlobalStateController final : public ServiceFramework<IGlobalStateController> {

View file

@ -12,8 +12,7 @@
#include "core/frontend/applets/profile_select.h"
#include "core/frontend/applets/software_keyboard.h"
#include "core/frontend/applets/web_browser.h"
#include "core/hle/kernel/k_readable_event.h"
#include "core/hle/kernel/k_writable_event.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/service/am/am.h"
#include "core/hle/service/am/applet_ae.h"
#include "core/hle/service/am/applet_oe.h"
@ -29,19 +28,19 @@
namespace Service::AM::Applets {
AppletDataBroker::AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_)
: system{system_}, applet_mode{applet_mode_}, state_changed_event{system.Kernel()},
pop_out_data_event{system.Kernel()}, pop_interactive_out_data_event{system.Kernel()} {
Kernel::KAutoObject::Create(std::addressof(state_changed_event));
Kernel::KAutoObject::Create(std::addressof(pop_out_data_event));
Kernel::KAutoObject::Create(std::addressof(pop_interactive_out_data_event));
state_changed_event.Initialize("ILibraryAppletAccessor:StateChangedEvent");
pop_out_data_event.Initialize("ILibraryAppletAccessor:PopDataOutEvent");
pop_interactive_out_data_event.Initialize("ILibraryAppletAccessor:PopInteractiveDataOutEvent");
: system{system_}, applet_mode{applet_mode_}, service_context{system,
"ILibraryAppletAccessor"} {
state_changed_event = service_context.CreateEvent("ILibraryAppletAccessor:StateChangedEvent");
pop_out_data_event = service_context.CreateEvent("ILibraryAppletAccessor:PopDataOutEvent");
pop_interactive_out_data_event =
service_context.CreateEvent("ILibraryAppletAccessor:PopInteractiveDataOutEvent");
}
AppletDataBroker::~AppletDataBroker() = default;
AppletDataBroker::~AppletDataBroker() {
service_context.CloseEvent(state_changed_event);
service_context.CloseEvent(pop_out_data_event);
service_context.CloseEvent(pop_interactive_out_data_event);
}
AppletDataBroker::RawChannelData AppletDataBroker::PeekDataToAppletForDebug() const {
std::vector<std::vector<u8>> out_normal;
@ -65,7 +64,7 @@ std::shared_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() {
auto out = std::move(out_channel.front());
out_channel.pop_front();
pop_out_data_event.GetWritableEvent().Clear();
pop_out_data_event->GetWritableEvent().Clear();
return out;
}
@ -84,7 +83,7 @@ std::shared_ptr<IStorage> AppletDataBroker::PopInteractiveDataToGame() {
auto out = std::move(out_interactive_channel.front());
out_interactive_channel.pop_front();
pop_interactive_out_data_event.GetWritableEvent().Clear();
pop_interactive_out_data_event->GetWritableEvent().Clear();
return out;
}
@ -103,7 +102,7 @@ void AppletDataBroker::PushNormalDataFromGame(std::shared_ptr<IStorage>&& storag
void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage) {
out_channel.emplace_back(std::move(storage));
pop_out_data_event.GetWritableEvent().Signal();
pop_out_data_event->GetWritableEvent().Signal();
}
void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage) {
@ -112,11 +111,11 @@ void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& s
void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage) {
out_interactive_channel.emplace_back(std::move(storage));
pop_interactive_out_data_event.GetWritableEvent().Signal();
pop_interactive_out_data_event->GetWritableEvent().Signal();
}
void AppletDataBroker::SignalStateChanged() {
state_changed_event.GetWritableEvent().Signal();
state_changed_event->GetWritableEvent().Signal();
switch (applet_mode) {
case LibraryAppletMode::AllForeground:
@ -141,15 +140,15 @@ void AppletDataBroker::SignalStateChanged() {
}
Kernel::KReadableEvent& AppletDataBroker::GetNormalDataEvent() {
return pop_out_data_event.GetReadableEvent();
return pop_out_data_event->GetReadableEvent();
}
Kernel::KReadableEvent& AppletDataBroker::GetInteractiveDataEvent() {
return pop_interactive_out_data_event.GetReadableEvent();
return pop_interactive_out_data_event->GetReadableEvent();
}
Kernel::KReadableEvent& AppletDataBroker::GetStateChangedEvent() {
return state_changed_event.GetReadableEvent();
return state_changed_event->GetReadableEvent();
}
Applet::Applet(Core::System& system_, LibraryAppletMode applet_mode_)

View file

@ -8,7 +8,7 @@
#include <queue>
#include "common/swap.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/service/kernel_helpers.h"
union ResultCode;
@ -105,6 +105,8 @@ private:
Core::System& system;
LibraryAppletMode applet_mode;
KernelHelpers::ServiceContext service_context;
// Queues are named from applet's perspective
// PopNormalDataToApplet and PushNormalDataFromGame
@ -119,13 +121,13 @@ private:
// PopInteractiveDataToGame and PushInteractiveDataFromApplet
std::deque<std::shared_ptr<IStorage>> out_interactive_channel;
Kernel::KEvent state_changed_event;
Kernel::KEvent* state_changed_event;
// Signaled on PushNormalDataFromApplet
Kernel::KEvent pop_out_data_event;
Kernel::KEvent* pop_out_data_event;
// Signaled on PushInteractiveDataFromApplet
Kernel::KEvent pop_interactive_out_data_event;
Kernel::KEvent* pop_interactive_out_data_event;
};
class Applet {