threads now end cleanly, and do so on exit

This commit is contained in:
zetaPRIME 2017-05-03 04:19:30 -04:00
parent 88d640f3e7
commit 5577b5a6a8
4 changed files with 36 additions and 4 deletions

View File

@ -17,6 +17,9 @@ using starlight::ThemeManager;
using starlight::InputManager;
using starlight::gfx::RenderCore;
using starlight::threading::Thread;
using starlight::threading::ThreadState;
using starlight::ui::TouchScreenCanvas;
using starlight::ui::TopScreenCanvas;
@ -83,6 +86,9 @@ void Application::_init() {
void Application::_end() {
End();
for (auto& thread : threads) thread->Exit();
threads.clear();
//for (auto& f : forms) f->Close();
forms.clear(); // not sure why, but not doing this results in a data abort if any forms are active
@ -159,8 +165,10 @@ void Application::_mainLoop() {
RenderCore::EndFrame();
while (!threads.empty() && frameTimer.GetSubframe() < 0.9) {
threads.front()->Resume();
if (threads.size() > 1) threads.splice(threads.end(), threads, threads.begin()); // move to back of queue
auto thread = threads.front();
thread->Resume();
if (thread->state != ThreadState::Finished) threads.splice(threads.end(), threads, threads.begin()); // move to back of queue
else threads.pop_front(); // or just discard if already exited
}
}

View File

@ -37,6 +37,9 @@ void Thread::_FinishStart() {
state = ThreadState::Running;
Yield();
Body();
state = ThreadState::Finished;
OnExit();
threadExit(0);
}
void Thread::Yield() {
@ -45,12 +48,30 @@ void Thread::Yield() {
svcWaitSynchronization(event, -1 /*U64_MAX*/);
//svcWaitSynchronization(event, 65536);
svcClearEvent(event);
if (state == ThreadState::Finished && OnExit()) {
threadExit(0);
}
state = ThreadState::Running;
}
void Thread::Exit() {
if (state == ThreadState::Idle) { // exited from outside
state = ThreadState::Finished;
Resume();
threadJoin(static_cast<SysThread>(sthread), -1);
} else if (state == ThreadState::Running) { // exited self
state = ThreadState::Finished;
OnExit();
threadExit(0);
}
}
void Thread::Resume() {
if (state != ThreadState::Idle) return; // not applicable
if (state != ThreadState::Idle && state != ThreadState::Finished) return; // not applicable
svcSignalEvent(event);
}
bool Thread::OnExit() { return true; } // default to "trivial" (no cleanup necessary)
//

View File

@ -30,8 +30,10 @@ namespace starlight {
void Enqueue();
void Yield();
void Resume();
void Exit();
virtual void Body() = 0;
virtual bool OnExit();
};
}
}

View File

@ -25,7 +25,8 @@ roadmap to v0.5.1 {
...and some mechanism for allowing it to opt out of the rest of the cycle
Trackable sideclass for threads; float progress 0..1, etc.
MAKE THREADS END CLEANLY
- MAKE THREADS END CLEANLY
^ observed a single instance of being stalled on redscreen, not really sure what that was about
}
} then by v0.5.5 {
event propagation system of some sort; threadsafe to whatever extent is needed on 3DS