summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/handle_table.cpp1
-rw-r--r--src/core/hle/kernel/init/init_slab_setup.cpp2
-rw-r--r--src/core/hle/kernel/k_event.cpp38
-rw-r--r--src/core/hle/kernel/k_event.h23
-rw-r--r--src/core/hle/kernel/object.h2
-rw-r--r--src/core/hle/kernel/svc.cpp9
6 files changed, 56 insertions, 19 deletions
diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp
index 427c6fc1b..58c49460f 100644
--- a/src/core/hle/kernel/handle_table.cpp
+++ b/src/core/hle/kernel/handle_table.cpp
@@ -53,6 +53,7 @@ ResultVal<Handle> HandleTable::Create(Object* obj) {
switch (obj->GetHandleType()) {
case HandleType::SharedMemory:
case HandleType::Thread:
+ case HandleType::Event:
case HandleType::Process: {
Handle handle{};
Add(&handle, reinterpret_cast<KAutoObject*>(obj), {});
diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp
index eb9c8e2e4..b292f7db2 100644
--- a/src/core/hle/kernel/init/init_slab_setup.cpp
+++ b/src/core/hle/kernel/init/init_slab_setup.cpp
@@ -9,6 +9,7 @@
#include "core/core.h"
#include "core/hardware_properties.h"
#include "core/hle/kernel/init/init_slab_setup.h"
+#include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_memory_manager.h"
#include "core/hle/kernel/k_shared_memory.h"
@@ -25,6 +26,7 @@ namespace Kernel::Init {
#define FOREACH_SLAB_TYPE(HANDLER, ...) \
HANDLER(Process, (SLAB_COUNT(Process)), ##__VA_ARGS__) \
HANDLER(KThread, (SLAB_COUNT(KThread)), ##__VA_ARGS__) \
+ HANDLER(KEvent, (SLAB_COUNT(KEvent)), ##__VA_ARGS__) \
HANDLER(KSharedMemory, (SLAB_COUNT(KSharedMemory)), ##__VA_ARGS__)
namespace {
diff --git a/src/core/hle/kernel/k_event.cpp b/src/core/hle/kernel/k_event.cpp
index bb2fa4ad5..bc4a79cc8 100644
--- a/src/core/hle/kernel/k_event.cpp
+++ b/src/core/hle/kernel/k_event.cpp
@@ -4,29 +4,53 @@
#include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_readable_event.h"
+#include "core/hle/kernel/k_resource_limit.h"
#include "core/hle/kernel/k_writable_event.h"
+#include "core/hle/kernel/process.h"
namespace Kernel {
-KEvent::KEvent(KernelCore& kernel, std::string&& name) : Object{kernel, std::move(name)} {}
+KEvent::KEvent(KernelCore& kernel) : KAutoObjectWithSlabHeapAndContainer{kernel} {}
KEvent::~KEvent() = default;
-std::shared_ptr<KEvent> KEvent::Create(KernelCore& kernel, std::string&& name) {
- return std::make_shared<KEvent>(kernel, std::move(name));
-}
+void KEvent::Initialize(std::string&& name_) {
+ // Increment reference count.
+ // Because reference count is one on creation, this will result
+ // in a reference count of two. Thus, when both readable and
+ // writable events are closed this object will be destroyed.
+ Open();
-void KEvent::Initialize() {
// Create our sub events.
- readable_event = std::make_shared<KReadableEvent>(kernel, GetName() + ":Readable");
- writable_event = std::make_shared<KWritableEvent>(kernel, GetName() + ":Writable");
+ readable_event = std::make_shared<KReadableEvent>(kernel, name_ + ":Readable");
+ writable_event = std::make_shared<KWritableEvent>(kernel, name_ + ":Writable");
// Initialize our sub sessions.
readable_event->Initialize(this);
writable_event->Initialize(this);
+ // Set our owner process.
+ owner = kernel.CurrentProcess();
+ if (owner) {
+ owner->Open();
+ }
+
// Mark initialized.
+ name = std::move(name_);
initialized = true;
}
+void KEvent::Finalize() {
+ KAutoObjectWithSlabHeapAndContainer<KEvent, KAutoObjectWithList>::Finalize();
+}
+
+void KEvent::PostDestroy(uintptr_t arg) {
+ // Release the event count resource the owner process holds.
+ Process* owner = reinterpret_cast<Process*>(arg);
+ if (owner) {
+ owner->GetResourceLimit()->Release(LimitableResource::Events, 1);
+ owner->Close();
+ }
+}
+
} // namespace Kernel
diff --git a/src/core/hle/kernel/k_event.h b/src/core/hle/kernel/k_event.h
index ec6894b16..97ec0ea9c 100644
--- a/src/core/hle/kernel/k_event.h
+++ b/src/core/hle/kernel/k_event.h
@@ -4,24 +4,34 @@
#pragma once
-#include "core/hle/kernel/object.h"
+#include "core/hle/kernel/slab_helpers.h"
namespace Kernel {
class KernelCore;
class KReadableEvent;
class KWritableEvent;
+class Process;
+
+class KEvent final : public KAutoObjectWithSlabHeapAndContainer<KEvent, KAutoObjectWithList> {
+ KERNEL_AUTOOBJECT_TRAITS(KEvent, KAutoObject);
-class KEvent final : public Object {
public:
- explicit KEvent(KernelCore& kernel, std::string&& name);
+ explicit KEvent(KernelCore& kernel);
~KEvent() override;
- static std::shared_ptr<KEvent> Create(KernelCore& kernel, std::string&& name);
+ void Initialize(std::string&& name);
+
+ virtual void Finalize() override;
- void Initialize();
+ virtual bool IsInitialized() const override {
+ return initialized;
+ }
+ virtual uintptr_t GetPostDestroyArgument() const override {
+ return reinterpret_cast<uintptr_t>(owner);
+ }
- void Finalize() override {}
+ static void PostDestroy(uintptr_t arg);
std::string GetTypeName() const override {
return "KEvent";
@@ -51,6 +61,7 @@ public:
private:
std::shared_ptr<KReadableEvent> readable_event;
std::shared_ptr<KWritableEvent> writable_event;
+ Process* owner{};
bool initialized{};
};
diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h
index 5c14aa46f..03443b947 100644
--- a/src/core/hle/kernel/object.h
+++ b/src/core/hle/kernel/object.h
@@ -71,6 +71,8 @@ protected:
private:
std::atomic<u32> object_id{0};
+
+protected:
std::string name;
};
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 17d63658a..b143a51c7 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1953,14 +1953,11 @@ static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* o
HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable();
// Create a new event.
- const auto event = KEvent::Create(kernel, "CreateEvent");
- if (!event) {
- LOG_ERROR(Kernel_SVC, "Unable to create new events. Event creation limit reached.");
- return ResultOutOfResource;
- }
+ KEvent* event = KEvent::CreateWithKernel(kernel);
+ R_UNLESS(event != nullptr, ResultOutOfResource);
// Initialize the event.
- event->Initialize();
+ event->Initialize("CreateEvent");
// Add the writable event to the handle table.
const auto write_create_result = handle_table.Create(event->GetWritableEvent().get());