mirror of
https://github.com/Atmosphere-NX/Atmosphere-libs.git
synced 2025-06-28 14:02:40 +02:00
Modernize C++ usage (#144)
* Stratosphere: Use modern C++ idioms in some places * algorithms like std::for_each are used instead of raw loops * Stratosphere: Replace more raw loops with algorithms * Stratosphere: Add a utility predicate function to test for equality with a reference element This can be used to rewrite some common raw loops using algorithms instead * fs.mitm: Use variant * fs.mitm: Use enum class * fs.mitm: Turn RomFSSourceInfo::Cleanup into a destructor This obsoletes the need for a custom deleter in other places * fs.mitm: Use enum class some more * fs.mitm: Use unique_ptr * fs.mitm: Simplify initialization * Stratosphere: Simplify initialization * fs.mitm: Use unique_ptr (fix memory leak along the way) The previous code was using "delete" rather than "delete[]" * fs.mitm: Use vector::emplace_back rather than push_back emplace_back constructs elements in-place, hence avoiding a redundant element copy. * Stratosphere: Replace more raw loops with algorithms * Stratosphere: Use unique_ptr * fs.mitm: Replace more raw loops with algorithms * Stratosphere: Prefer move-construction over copy-construction when moving sink parameters around
This commit is contained in:
parent
51edf0fde9
commit
1b356cd4f2
37
include/meta_tools.hpp
Normal file
37
include/meta_tools.hpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct class_of;
|
||||||
|
|
||||||
|
template<typename Ret, typename C>
|
||||||
|
struct class_of<Ret C::*> {
|
||||||
|
using type = C;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using class_of_t = typename class_of<T>::type;
|
||||||
|
|
||||||
|
template<typename Mem, typename T, typename C = class_of_t<Mem>>
|
||||||
|
struct member_equals_fn_helper {
|
||||||
|
T ref;
|
||||||
|
Mem mem_fn;
|
||||||
|
|
||||||
|
bool operator()(const C& val) const {
|
||||||
|
return (std::mem_fn(mem_fn)(val) == ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(C&& val) const {
|
||||||
|
return (std::mem_fn(mem_fn)(std::move(val)) == ref);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<typename Mem, typename T>
|
||||||
|
auto member_equals_fn(Mem mem, T ref) {
|
||||||
|
return detail::member_equals_fn_helper<Mem, T>{std::move(ref), std::move(mem)};
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
@ -11,18 +12,13 @@ class IServiceObject;
|
|||||||
|
|
||||||
class DomainOwner {
|
class DomainOwner {
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<IServiceObject> domain_objects[DOMAIN_ID_MAX];
|
std::array<std::shared_ptr<IServiceObject>, DOMAIN_ID_MAX> domain_objects;
|
||||||
public:
|
public:
|
||||||
DomainOwner() {
|
DomainOwner() = default;
|
||||||
for (unsigned int i = 0; i < DOMAIN_ID_MAX; i++) {
|
|
||||||
domain_objects[i].reset();
|
/* Shared ptrs should auto delete here. */
|
||||||
}
|
virtual ~DomainOwner() = default;
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~DomainOwner() {
|
|
||||||
/* Shared ptrs should auto delete here. */
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<IServiceObject> get_domain_object(unsigned int i) {
|
std::shared_ptr<IServiceObject> get_domain_object(unsigned int i) {
|
||||||
if (i < DOMAIN_ID_MAX) {
|
if (i < DOMAIN_ID_MAX) {
|
||||||
return domain_objects[i];
|
return domain_objects[i];
|
||||||
@ -31,20 +27,20 @@ class DomainOwner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result reserve_object(std::shared_ptr<IServiceObject> object, unsigned int *out_i) {
|
Result reserve_object(std::shared_ptr<IServiceObject> object, unsigned int *out_i) {
|
||||||
for (unsigned int i = 4; i < DOMAIN_ID_MAX; i++) {
|
auto object_it = std::find(domain_objects.begin() + 4, domain_objects.end(), nullptr);
|
||||||
if (domain_objects[i] == NULL) {
|
if (object_it == domain_objects.end()) {
|
||||||
domain_objects[i] = object;
|
return 0x1900B;
|
||||||
object->set_owner(this);
|
|
||||||
*out_i = i;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0x1900B;
|
|
||||||
|
*out_i = std::distance(domain_objects.begin(), object_it);
|
||||||
|
*object_it = std::move(object);
|
||||||
|
(*object_it)->set_owner(this);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result set_object(std::shared_ptr<IServiceObject> object, unsigned int i) {
|
Result set_object(std::shared_ptr<IServiceObject> object, unsigned int i) {
|
||||||
if (domain_objects[i] == NULL) {
|
if (domain_objects[i] == NULL) {
|
||||||
domain_objects[i] = object;
|
domain_objects[i] = std::move(object);
|
||||||
object->set_owner(this);
|
object->set_owner(this);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -52,26 +48,18 @@ class DomainOwner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned int get_object_id(std::shared_ptr<IServiceObject> object) {
|
unsigned int get_object_id(std::shared_ptr<IServiceObject> object) {
|
||||||
for (unsigned int i = 0; i < DOMAIN_ID_MAX; i++) {
|
auto object_it = std::find(domain_objects.begin(), domain_objects.end(), object);
|
||||||
if (domain_objects[i] == object) {
|
return std::distance(domain_objects.begin(), object_it);
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return DOMAIN_ID_MAX;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void delete_object(unsigned int i) {
|
void delete_object(unsigned int i) {
|
||||||
if (domain_objects[i]) {
|
domain_objects[i].reset();
|
||||||
domain_objects[i].reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void delete_object(std::shared_ptr<IServiceObject> object) {
|
void delete_object(std::shared_ptr<IServiceObject> object) {
|
||||||
for (unsigned int i = 0; i < DOMAIN_ID_MAX; i++) {
|
auto object_it = std::find(domain_objects.begin(), domain_objects.end(), object);
|
||||||
if (domain_objects[i] == object) {
|
if (object_it != domain_objects.end()) {
|
||||||
domain_objects[i].reset();
|
object_it->reset();
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "iwaitable.hpp"
|
#include "iwaitable.hpp"
|
||||||
@ -22,9 +23,7 @@ class IEvent : public IWaitable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
~IEvent() {
|
~IEvent() {
|
||||||
for (auto &h : this->handles) {
|
std::for_each(handles.begin(), handles.end(), svcCloseHandle);
|
||||||
svcCloseHandle(h);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result signal_event() = 0;
|
virtual Result signal_event() = 0;
|
||||||
@ -50,4 +49,4 @@ class IEvent : public IWaitable {
|
|||||||
/* TODO: Panic. */
|
/* TODO: Panic. */
|
||||||
return 0xCAFE;
|
return 0xCAFE;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -18,9 +18,7 @@ class IPCSession final : public ISession<T> {
|
|||||||
fatalSimple(rc);
|
fatalSimple(rc);
|
||||||
}
|
}
|
||||||
this->service_object = std::make_shared<T>();
|
this->service_object = std::make_shared<T>();
|
||||||
this->pointer_buffer_size = pbs;
|
this->pointer_buffer.resize(pbs);
|
||||||
this->pointer_buffer = new char[this->pointer_buffer_size];
|
|
||||||
this->is_domain = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCSession<T>(std::shared_ptr<T> so, size_t pbs = 0x400) : ISession<T>(NULL, 0, 0, so, 0) {
|
IPCSession<T>(std::shared_ptr<T> so, size_t pbs = 0x400) : ISession<T>(NULL, 0, 0, so, 0) {
|
||||||
@ -28,8 +26,6 @@ class IPCSession final : public ISession<T> {
|
|||||||
if (R_FAILED((rc = svcCreateSession(&this->server_handle, &this->client_handle, 0, 0)))) {
|
if (R_FAILED((rc = svcCreateSession(&this->server_handle, &this->client_handle, 0, 0)))) {
|
||||||
fatalSimple(rc);
|
fatalSimple(rc);
|
||||||
}
|
}
|
||||||
this->pointer_buffer_size = pbs;
|
this->pointer_buffer.resize(pbs);
|
||||||
this->pointer_buffer = new char[this->pointer_buffer_size];
|
|
||||||
this->is_domain = false;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
#include <algorithm>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include "iserviceobject.hpp"
|
#include "iserviceobject.hpp"
|
||||||
@ -51,4 +52,4 @@ class IServer : public IWaitable {
|
|||||||
this->get_manager()->add_waitable(this->get_new_session(session_h));
|
this->get_manager()->add_waitable(this->get_new_session(session_h));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -17,7 +17,6 @@ enum IpcControlCommand {
|
|||||||
IpcCtrl_Cmd_CloneCurrentObjectEx = 4
|
IpcCtrl_Cmd_CloneCurrentObjectEx = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
#define POINTER_BUFFER_SIZE_MAX 0xFFFF
|
|
||||||
#define RESULT_DEFER_SESSION (0x6580A)
|
#define RESULT_DEFER_SESSION (0x6580A)
|
||||||
|
|
||||||
|
|
||||||
@ -34,39 +33,23 @@ class ISession : public IWaitable {
|
|||||||
IServer<T> *server;
|
IServer<T> *server;
|
||||||
Handle server_handle;
|
Handle server_handle;
|
||||||
Handle client_handle;
|
Handle client_handle;
|
||||||
char *pointer_buffer;
|
std::vector<char> pointer_buffer;
|
||||||
size_t pointer_buffer_size;
|
|
||||||
|
|
||||||
bool is_domain;
|
bool is_domain = false;
|
||||||
std::shared_ptr<DomainOwner> domain;
|
std::shared_ptr<DomainOwner> domain;
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<IServiceObject> active_object;
|
std::shared_ptr<IServiceObject> active_object;
|
||||||
|
|
||||||
static_assert(sizeof(pointer_buffer) <= POINTER_BUFFER_SIZE_MAX, "Incorrect Size for PointerBuffer!");
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ISession<T>(IServer<T> *s, Handle s_h, Handle c_h, size_t pbs = 0x400) : server(s), server_handle(s_h), client_handle(c_h), pointer_buffer_size(pbs) {
|
ISession<T>(IServer<T> *s, Handle s_h, Handle c_h, size_t pbs = 0x400) : server(s), server_handle(s_h), client_handle(c_h), pointer_buffer(pbs) {
|
||||||
this->service_object = std::make_shared<T>();
|
this->service_object = std::make_shared<T>();
|
||||||
if (this->pointer_buffer_size) {
|
|
||||||
this->pointer_buffer = new char[this->pointer_buffer_size];
|
|
||||||
}
|
|
||||||
this->is_domain = false;
|
|
||||||
this->domain.reset();
|
|
||||||
this->active_object.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ISession<T>(IServer<T> *s, Handle s_h, Handle c_h, std::shared_ptr<T> so, size_t pbs = 0x400) : service_object(so), server(s), server_handle(s_h), client_handle(c_h), pointer_buffer_size(pbs) {
|
ISession<T>(IServer<T> *s, Handle s_h, Handle c_h, std::shared_ptr<T> so, size_t pbs = 0x400) : service_object(so), server(s), server_handle(s_h), client_handle(c_h), pointer_buffer(pbs) {
|
||||||
if (this->pointer_buffer_size) {
|
|
||||||
this->pointer_buffer = new char[this->pointer_buffer_size];
|
|
||||||
}
|
|
||||||
this->is_domain = false;
|
|
||||||
this->domain.reset();
|
|
||||||
this->active_object.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~ISession() override {
|
~ISession() override {
|
||||||
delete this->pointer_buffer;
|
|
||||||
if (server_handle) {
|
if (server_handle) {
|
||||||
svcCloseHandle(server_handle);
|
svcCloseHandle(server_handle);
|
||||||
}
|
}
|
||||||
@ -153,7 +136,7 @@ class ISession : public IWaitable {
|
|||||||
break;
|
break;
|
||||||
case IpcCommandType_Request:
|
case IpcCommandType_Request:
|
||||||
case IpcCommandType_RequestWithContext:
|
case IpcCommandType_RequestWithContext:
|
||||||
retval = this->active_object->dispatch(r, c, cmd_id, (u8 *)this->pointer_buffer, this->pointer_buffer_size);
|
retval = this->active_object->dispatch(r, c, cmd_id, (u8 *)pointer_buffer.data(), pointer_buffer.size());
|
||||||
break;
|
break;
|
||||||
case IpcCommandType_Control:
|
case IpcCommandType_Control:
|
||||||
case IpcCommandType_ControlWithContext:
|
case IpcCommandType_ControlWithContext:
|
||||||
@ -185,7 +168,7 @@ class ISession : public IWaitable {
|
|||||||
/* Prepare pointer buffer... */
|
/* Prepare pointer buffer... */
|
||||||
IpcCommand c_for_reply;
|
IpcCommand c_for_reply;
|
||||||
ipcInitialize(&c_for_reply);
|
ipcInitialize(&c_for_reply);
|
||||||
ipcAddRecvStatic(&c_for_reply, this->pointer_buffer, this->pointer_buffer_size, 0);
|
ipcAddRecvStatic(&c_for_reply, this->pointer_buffer.data(), this->pointer_buffer.size(), 0);
|
||||||
ipcPrepareHeader(&c_for_reply, 0);
|
ipcPrepareHeader(&c_for_reply, 0);
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc = svcReplyAndReceive(&handle_index, &this->server_handle, 1, 0, U64_MAX))) {
|
if (R_SUCCEEDED(rc = svcReplyAndReceive(&handle_index, &this->server_handle, 1, 0, U64_MAX))) {
|
||||||
@ -247,19 +230,19 @@ class ISession : public IWaitable {
|
|||||||
/* TODO: Implement. */
|
/* TODO: Implement. */
|
||||||
switch ((IpcControlCommand)cmd_id) {
|
switch ((IpcControlCommand)cmd_id) {
|
||||||
case IpcCtrl_Cmd_ConvertCurrentObjectToDomain:
|
case IpcCtrl_Cmd_ConvertCurrentObjectToDomain:
|
||||||
rc = WrapIpcCommandImpl<&ISession::ConvertCurrentObjectToDomain>(this, r, out_c, (u8 *)this->pointer_buffer, this->pointer_buffer_size);
|
rc = WrapIpcCommandImpl<&ISession::ConvertCurrentObjectToDomain>(this, r, out_c, (u8 *)this->pointer_buffer.data(), pointer_buffer.size());
|
||||||
break;
|
break;
|
||||||
case IpcCtrl_Cmd_CopyFromCurrentDomain:
|
case IpcCtrl_Cmd_CopyFromCurrentDomain:
|
||||||
rc = WrapIpcCommandImpl<&ISession::CopyFromCurrentDomain>(this, r, out_c, (u8 *)this->pointer_buffer, this->pointer_buffer_size);
|
rc = WrapIpcCommandImpl<&ISession::CopyFromCurrentDomain>(this, r, out_c, (u8 *)this->pointer_buffer.data(), pointer_buffer.size());
|
||||||
break;
|
break;
|
||||||
case IpcCtrl_Cmd_CloneCurrentObject:
|
case IpcCtrl_Cmd_CloneCurrentObject:
|
||||||
rc = WrapIpcCommandImpl<&ISession::CloneCurrentObject>(this, r, out_c, (u8 *)this->pointer_buffer, this->pointer_buffer_size);
|
rc = WrapIpcCommandImpl<&ISession::CloneCurrentObject>(this, r, out_c, (u8 *)this->pointer_buffer.data(), pointer_buffer.size());
|
||||||
break;
|
break;
|
||||||
case IpcCtrl_Cmd_QueryPointerBufferSize:
|
case IpcCtrl_Cmd_QueryPointerBufferSize:
|
||||||
rc = WrapIpcCommandImpl<&ISession::QueryPointerBufferSize>(this, r, out_c, (u8 *)this->pointer_buffer, this->pointer_buffer_size);
|
rc = WrapIpcCommandImpl<&ISession::QueryPointerBufferSize>(this, r, out_c, (u8 *)this->pointer_buffer.data(), pointer_buffer.size());
|
||||||
break;
|
break;
|
||||||
case IpcCtrl_Cmd_CloneCurrentObjectEx:
|
case IpcCtrl_Cmd_CloneCurrentObjectEx:
|
||||||
rc = WrapIpcCommandImpl<&ISession::CloneCurrentObjectEx>(this, r, out_c, (u8 *)this->pointer_buffer, sizeof(this->pointer_buffer));
|
rc = WrapIpcCommandImpl<&ISession::CloneCurrentObjectEx>(this, r, out_c, (u8 *)this->pointer_buffer.data(), pointer_buffer.size());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -282,7 +265,7 @@ class ISession : public IWaitable {
|
|||||||
return {0xF601};
|
return {0xF601};
|
||||||
}
|
}
|
||||||
std::tuple<Result, u32> QueryPointerBufferSize() {
|
std::tuple<Result, u32> QueryPointerBufferSize() {
|
||||||
return {0x0, (u32)this->pointer_buffer_size};
|
return {0x0, (u32)this->pointer_buffer.size()};
|
||||||
}
|
}
|
||||||
std::tuple<Result> CloneCurrentObjectEx() {
|
std::tuple<Result> CloneCurrentObjectEx() {
|
||||||
/* TODO */
|
/* TODO */
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "waitablemanagerbase.hpp"
|
#include "waitablemanagerbase.hpp"
|
||||||
@ -12,22 +14,19 @@ class WaitableManager : public WaitableManagerBase {
|
|||||||
protected:
|
protected:
|
||||||
std::vector<IWaitable *> to_add_waitables;
|
std::vector<IWaitable *> to_add_waitables;
|
||||||
std::vector<IWaitable *> waitables;
|
std::vector<IWaitable *> waitables;
|
||||||
u64 timeout;
|
u64 timeout = 0;
|
||||||
HosMutex lock;
|
HosMutex lock;
|
||||||
std::atomic_bool has_new_items;
|
std::atomic_bool has_new_items = false;
|
||||||
private:
|
private:
|
||||||
void process_internal(bool break_on_timeout);
|
void process_internal(bool break_on_timeout);
|
||||||
public:
|
public:
|
||||||
WaitableManager(u64 t) : waitables(0), timeout(t), has_new_items(false) { }
|
WaitableManager(u64 t) : timeout(t) { }
|
||||||
~WaitableManager() override {
|
~WaitableManager() override {
|
||||||
/* This should call the destructor for every waitable. */
|
/* This should call the destructor for every waitable. */
|
||||||
for (auto & waitable : waitables) {
|
std::for_each(waitables.begin(), waitables.end(), std::default_delete<IWaitable>{});
|
||||||
delete waitable;
|
|
||||||
}
|
|
||||||
waitables.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void add_waitable(IWaitable *waitable);
|
virtual void add_waitable(IWaitable *waitable);
|
||||||
virtual void process();
|
virtual void process();
|
||||||
virtual void process_until_timeout();
|
virtual void process_until_timeout();
|
||||||
};
|
};
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class WaitableManagerBase {
|
class WaitableManagerBase {
|
||||||
std::atomic<u64> cur_priority;
|
std::atomic<u64> cur_priority = 0;
|
||||||
public:
|
public:
|
||||||
WaitableManagerBase() : cur_priority(0) { }
|
WaitableManagerBase() = default;
|
||||||
virtual ~WaitableManagerBase() { }
|
virtual ~WaitableManagerBase() = default;
|
||||||
|
|
||||||
u64 get_priority() {
|
u64 get_priority() {
|
||||||
return std::atomic_fetch_add(&cur_priority, (u64)1);
|
return std::atomic_fetch_add(&cur_priority, (u64)1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include <stratosphere/multithreadedwaitablemanager.hpp>
|
#include <stratosphere/multithreadedwaitablemanager.hpp>
|
||||||
|
|
||||||
@ -44,21 +45,15 @@ IWaitable *MultiThreadedWaitableManager::get_waitable() {
|
|||||||
rc = svcWaitSynchronization(&handle_index, handles.data(), this->waitables.size(), this->timeout);
|
rc = svcWaitSynchronization(&handle_index, handles.data(), this->waitables.size(), this->timeout);
|
||||||
IWaitable *w = this->waitables[handle_index];
|
IWaitable *w = this->waitables[handle_index];
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
for (int i = 0; i < handle_index; i++) {
|
std::for_each(waitables.begin(), waitables.begin() + handle_index, std::mem_fn(&IWaitable::update_priority));
|
||||||
this->waitables[i]->update_priority();
|
|
||||||
}
|
|
||||||
this->waitables.erase(this->waitables.begin() + handle_index);
|
this->waitables.erase(this->waitables.begin() + handle_index);
|
||||||
} else if (rc == 0xEA01) {
|
} else if (rc == 0xEA01) {
|
||||||
/* Timeout. */
|
/* Timeout. */
|
||||||
for (auto & waitable : this->waitables) {
|
std::for_each(waitables.begin(), waitables.end(), std::mem_fn(&IWaitable::update_priority));
|
||||||
waitable->update_priority();
|
|
||||||
}
|
|
||||||
} else if (rc != 0xF601 && rc != 0xE401) {
|
} else if (rc != 0xF601 && rc != 0xE401) {
|
||||||
/* TODO: Panic. When can this happen? */
|
/* TODO: Panic. When can this happen? */
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < handle_index; i++) {
|
std::for_each(waitables.begin(), waitables.begin() + handle_index, std::mem_fn(&IWaitable::update_priority));
|
||||||
this->waitables[i]->update_priority();
|
|
||||||
}
|
|
||||||
this->waitables.erase(this->waitables.begin() + handle_index);
|
this->waitables.erase(this->waitables.begin() + handle_index);
|
||||||
delete w;
|
delete w;
|
||||||
}
|
}
|
||||||
@ -107,4 +102,4 @@ void MultiThreadedWaitableManager::thread_func(void *t) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include <stratosphere/waitablemanager.hpp>
|
#include <stratosphere/waitablemanager.hpp>
|
||||||
|
|
||||||
@ -43,14 +44,10 @@ void WaitableManager::process_internal(bool break_on_timeout) {
|
|||||||
|
|
||||||
rc = this->waitables[handle_index]->handle_signaled(0);
|
rc = this->waitables[handle_index]->handle_signaled(0);
|
||||||
|
|
||||||
for (int i = 0; i < handle_index; i++) {
|
std::for_each(waitables.begin(), waitables.begin() + handle_index, std::mem_fn(&IWaitable::update_priority));
|
||||||
this->waitables[i]->update_priority();
|
|
||||||
}
|
|
||||||
} else if (rc == 0xEA01) {
|
} else if (rc == 0xEA01) {
|
||||||
/* Timeout. */
|
/* Timeout. */
|
||||||
for (auto & waitable : this->waitables) {
|
std::for_each(waitables.begin(), waitables.end(), std::mem_fn(&IWaitable::update_priority));
|
||||||
waitable->update_priority();
|
|
||||||
}
|
|
||||||
if (break_on_timeout) {
|
if (break_on_timeout) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -72,9 +69,7 @@ void WaitableManager::process_internal(bool break_on_timeout) {
|
|||||||
/* Delete it. */
|
/* Delete it. */
|
||||||
delete to_delete;
|
delete to_delete;
|
||||||
|
|
||||||
for (int i = 0; i < handle_index; i++) {
|
std::for_each(waitables.begin(), waitables.begin() + handle_index, std::mem_fn(&IWaitable::update_priority));
|
||||||
this->waitables[i]->update_priority();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do deferred callback for each waitable. */
|
/* Do deferred callback for each waitable. */
|
||||||
@ -92,4 +87,4 @@ void WaitableManager::process() {
|
|||||||
|
|
||||||
void WaitableManager::process_until_timeout() {
|
void WaitableManager::process_until_timeout() {
|
||||||
WaitableManager::process_internal(true);
|
WaitableManager::process_internal(true);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user