Compare commits

...

4 Commits

Author SHA1 Message Date
Balázs Triszka
8766f68e16 Merge branch 'master' into master 2018-09-20 23:50:26 +02:00
balika011
daa9ff3870 hle: fix service freeing problems
ServiceFrameworkBase had a pointer to ServerPort that had a pointer to ServiceFrameworkBase -> never free
2018-09-14 09:41:08 +02:00
balika011
2af55f6589 kernel: fix free scheduler and thread
the scheduler had a shared pointer to the thread, the thread had a shared pointer to the scheduler
resulting in not freeing non of them
2018-09-14 05:35:40 +02:00
balika011
04dbdeaa2f hle: fix crash in UpdatePadCallback on non-first start
We need to call ReloadInputDevices() or UpdatePadCallback will crash because LoadInputDevices won't be called.
2018-09-14 05:32:52 +02:00
7 changed files with 21 additions and 38 deletions

View File

@@ -51,7 +51,8 @@ void Thread::Stop() {
// Clean up thread from ready queue
// This is only needed when the thread is terminated forcefully (SVC TerminateProcess)
if (status == ThreadStatus::Ready) {
scheduler->UnscheduleThread(this, current_priority);
if (auto schlr = scheduler.lock())
schlr->UnscheduleThread(this, current_priority);
}
status = ThreadStatus::Dead;
@@ -161,14 +162,16 @@ void Thread::ResumeFromWait() {
if (*new_processor_id != processor_id) {
// Remove thread from previous core's scheduler
scheduler->RemoveThread(this);
if (auto schlr = scheduler.lock())
schlr->RemoveThread(this);
next_scheduler->AddThread(this, current_priority);
}
processor_id = *new_processor_id;
// If the thread was ready, unschedule from the previous core and schedule on the new core
scheduler->UnscheduleThread(this, current_priority);
if (auto schlr = scheduler.lock())
schlr->UnscheduleThread(this, current_priority);
next_scheduler->ScheduleThread(this, current_priority);
// Change thread's scheduler
@@ -263,7 +266,8 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name
thread->callback_handle = kernel.ThreadWakeupCallbackHandleTable().Create(thread).Unwrap();
thread->owner_process = owner_process;
thread->scheduler = Core::System::GetInstance().Scheduler(processor_id);
thread->scheduler->AddThread(thread, priority);
if (auto s = thread->scheduler.lock())
s->AddThread(thread, priority);
// Find the next available TLS index, and mark it as used
auto& tls_slots = owner_process->tls_slots;
@@ -306,7 +310,8 @@ void Thread::SetPriority(u32 priority) {
}
void Thread::BoostPriority(u32 priority) {
scheduler->SetThreadPriority(this, priority);
if (auto schlr = scheduler.lock())
schlr->SetThreadPriority(this, priority);
current_priority = priority;
}
@@ -396,7 +401,8 @@ void Thread::UpdatePriority() {
if (new_priority == current_priority)
return;
scheduler->SetThreadPriority(this, new_priority);
if (auto schlr = scheduler.lock())
schlr->SetThreadPriority(this, new_priority);
current_priority = new_priority;
@@ -430,14 +436,16 @@ void Thread::ChangeCore(u32 core, u64 mask) {
if (*new_processor_id != processor_id) {
// Remove thread from previous core's scheduler
scheduler->RemoveThread(this);
if (auto schlr = scheduler.lock())
schlr->RemoveThread(this);
next_scheduler->AddThread(this, current_priority);
}
processor_id = *new_processor_id;
// If the thread was ready, unschedule from the previous core and schedule on the new core
scheduler->UnscheduleThread(this, current_priority);
if (auto schlr = scheduler.lock())
schlr->UnscheduleThread(this, current_priority);
next_scheduler->ScheduleThread(this, current_priority);
// Change thread's scheduler

View File

@@ -260,7 +260,7 @@ public:
// available. In case of a timeout, the object will be nullptr.
std::function<WakeupCallback> wakeup_callback;
std::shared_ptr<Scheduler> scheduler;
std::weak_ptr<Scheduler> scheduler;
u32 ideal_core{0xFFFFFFFF};
u64 affinity_mask{0x1};

View File

@@ -292,6 +292,8 @@ private:
class Hid final : public ServiceFramework<Hid> {
public:
Hid() : ServiceFramework("hid") {
ReloadInputDevices();
// clang-format off
static const FunctionInfo functions[] = {
{0, &Hid::CreateAppletResource, "CreateAppletResource"},

View File

@@ -99,14 +99,12 @@ ServiceFrameworkBase::ServiceFrameworkBase(const char* service_name, u32 max_ses
ServiceFrameworkBase::~ServiceFrameworkBase() = default;
void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager) {
ASSERT(port == nullptr);
port = service_manager.RegisterService(service_name, max_sessions).Unwrap();
SharedPtr<ServerPort> port =
service_manager.RegisterService(service_name, max_sessions).Unwrap();
port->SetHleHandler(shared_from_this());
}
void ServiceFrameworkBase::InstallAsNamedPort() {
ASSERT(port == nullptr);
auto& kernel = Core::System::GetInstance().Kernel();
SharedPtr<ServerPort> server_port;
SharedPtr<ClientPort> client_port;
@@ -116,19 +114,6 @@ void ServiceFrameworkBase::InstallAsNamedPort() {
kernel.AddNamedPort(service_name, std::move(client_port));
}
Kernel::SharedPtr<Kernel::ClientPort> ServiceFrameworkBase::CreatePort() {
ASSERT(port == nullptr);
auto& kernel = Core::System::GetInstance().Kernel();
Kernel::SharedPtr<Kernel::ServerPort> server_port;
Kernel::SharedPtr<Kernel::ClientPort> client_port;
std::tie(server_port, client_port) =
Kernel::ServerPort::CreatePortPair(kernel, max_sessions, service_name);
port = MakeResult<Kernel::SharedPtr<Kernel::ServerPort>>(std::move(server_port)).Unwrap();
port->SetHleHandler(shared_from_this());
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) {

View File

@@ -60,8 +60,6 @@ public:
void InstallAsService(SM::ServiceManager& service_manager);
/// Creates a port pair and registers it on the kernel's global port registry.
void InstallAsNamedPort();
/// Creates and returns an unregistered port for the service.
Kernel::SharedPtr<Kernel::ClientPort> CreatePort();
void InvokeRequest(Kernel::HLERequestContext& ctx);
@@ -96,12 +94,6 @@ private:
/// Maximum number of concurrent sessions that this service can handle.
u32 max_sessions;
/**
* Port where incoming connections will be received. Only created when InstallAsService() or
* InstallAsNamedPort() are called.
*/
Kernel::SharedPtr<Kernel::ServerPort> port;
/// 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;

View File

@@ -37,11 +37,8 @@ static ResultCode ValidateServiceName(const std::string& name) {
}
void ServiceManager::InstallInterfaces(std::shared_ptr<ServiceManager> self) {
ASSERT(self->sm_interface.expired());
auto sm = std::make_shared<SM>(self);
sm->InstallAsNamedPort();
self->sm_interface = sm;
self->controller_interface = std::make_unique<Controller>();
}

View File

@@ -51,7 +51,6 @@ public:
void InvokeControlRequest(Kernel::HLERequestContext& context);
private:
std::weak_ptr<SM> sm_interface;
std::unique_ptr<Controller> controller_interface;
/// Map of registered services, retrieved using GetServicePort or ConnectToService.