Skip to content

Commit ed2f63e

Browse files
committed
Reworking/simplifying exit strategy.
1 parent fce821d commit ed2f63e

File tree

2 files changed

+24
-21
lines changed

2 files changed

+24
-21
lines changed

src/core/system.h

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,12 @@ class System {
163163
// Close mem and plugins
164164
virtual void close() = 0;
165165
virtual void purgeAllEvents() = 0;
166-
bool running() { return m_running; }
166+
bool running() {
167+
std::atomic_signal_fence(std::memory_order_relaxed);
168+
return m_running && !m_quitting;
169+
}
167170
const bool *runningPtr() { return &m_running; }
168171
bool quitting() { return m_quitting; }
169-
bool terminating() { return m_terminating; }
170172
int exitCode() { return m_exitCode; }
171173
bool emergencyExit() { return m_emergencyExit; }
172174
[[gnu::cold]] void pause(bool exception = false) {
@@ -175,22 +177,15 @@ class System {
175177
m_eventBus->signal(Events::ExecutionFlow::Pause{exception});
176178
}
177179
void resume() {
178-
if (m_running || m_terminating) return;
180+
if (m_running) return;
179181
m_running = true;
180182
m_eventBus->signal(Events::ExecutionFlow::Run{});
181183
}
182184
virtual void testQuit(int code) = 0;
183-
[[gnu::cold]] void terminateSignalSafe() {
184-
// about the only thing signal handlers can do safely is switch a flag
185-
m_terminating = true;
186-
m_running = false;
187-
}
185+
// This needs to only mutate variables, as it requires to be signal-safe.
188186
[[gnu::cold]] void quit(int code = 0) {
189187
m_quitting = true;
190-
pause();
191188
m_exitCode = code;
192-
m_eventBus->signal(Events::Quitting{});
193-
purgeAllEvents();
194189
}
195190

196191
std::shared_ptr<EventBus::EventBus> m_eventBus = std::make_shared<EventBus::EventBus>();
@@ -263,9 +258,18 @@ class System {
263258
std::map<uint64_t, std::string> m_i18n;
264259
std::map<std::string, decltype(m_i18n)> m_locales;
265260
std::string m_currentLocale;
261+
// If true, indicates that the emulator is currently capturing the main loop
262+
// and actively emulates the PSX hardware. If false, the emulator is paused,
263+
// waiting for user input or other events inside the UI. The way the UI
264+
// is refreshed is by calling update() periodically, so this boolean affects
265+
// the moment when and how update() is called.
266266
bool m_running = false;
267+
// If true, indicates that the emulator is quitting. This can be set by a
268+
// number of events, including the user pressing the quit button or the
269+
// emulator itself requesting a quit due to testing for instance. This will
270+
// cause the two main loop to exit: the inner one being the emulator itself,
271+
// and the outer one being the main.cc loop.
267272
bool m_quitting = false;
268-
bool m_terminating = false;
269273
int m_exitCode = 0;
270274
struct LocaleInfo {
271275
const std::string filename;

src/main/main.cc

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,6 @@ class SystemImpl final : public PCSX::System {
116116
// emulator is requesting a shutdown of the emulation
117117
}
118118

119-
virtual void purgeAllEvents() final override { uv_run(getLoop(), UV_RUN_DEFAULT); }
120-
121119
virtual void testQuit(int code) final override {
122120
if (m_args.isTestModeEnabled()) {
123121
quit(code);
@@ -134,6 +132,8 @@ class SystemImpl final : public PCSX::System {
134132
const PCSX::Arguments m_args;
135133

136134
public:
135+
virtual void purgeAllEvents() final override { uv_run(getLoop(), UV_RUN_DEFAULT); }
136+
137137
void setBinDir(std::filesystem::path path) {
138138
m_binDir = path;
139139
m_version.loadFromFile(new PCSX::PosixFile(path / "version.json"));
@@ -167,7 +167,7 @@ struct Cleaner {
167167
};
168168

169169
void handleSignal(int signal) {
170-
PCSX::g_system->terminateSignalSafe();
170+
PCSX::g_system->quit(-1);
171171
}
172172

173173
int pcsxMain(int argc, char **argv) {
@@ -454,15 +454,14 @@ runner.init({
454454
emulator->m_cpu->Execute();
455455
} else {
456456
// The "update" method will be called periodically by the emulator while
457-
// meaning if we want our UI to work, we have to manually call "update"
458-
// when the emulator is paused.
457+
// it's running, meaning if we want our UI to work, we have to manually
458+
// call "update" when the emulator is paused.
459459
s_ui->update();
460460
}
461-
if (system->terminating()) {
462-
PCSX::g_system->quit(-1);
463-
return exitCode;
464-
}
465461
}
462+
system->pause();
463+
system->m_eventBus->signal(PCSX::Events::Quitting{});
464+
system->purgeAllEvents();
466465
} catch (...) {
467466
// This will ensure we don't do certain cleanups that are awaiting other tasks,
468467
// which could result in deadlocks on exit in case we encountered a serious problem.

0 commit comments

Comments
 (0)