Cleanup shutdown on Windows to avoid races.

Was still getting crashes sometimes.
This commit is contained in:
Unknown W. Brackets 2013-10-12 01:40:33 -07:00
parent 85c013c5b6
commit 21f522746f
5 changed files with 64 additions and 43 deletions

View File

@ -127,39 +127,53 @@ void UpdateScreenScale() {
pixel_in_dps = (float)pixel_xres / dp_xres;
}
static inline void UpdateRunLoop() {
UpdateScreenScale();
{
{
#ifdef _WIN32
lock_guard guard(input_state.lock);
input_state.pad_buttons = 0;
input_state.pad_lstick_x = 0;
input_state.pad_lstick_y = 0;
input_state.pad_rstick_x = 0;
input_state.pad_rstick_y = 0;
host->PollControllers(input_state);
UpdateInputState(&input_state);
#endif
}
NativeUpdate(input_state);
EndInputState(&input_state);
}
NativeRender();
}
void Core_RunLoop()
{
while (globalUIState != UISTATE_INGAME && globalUIState != UISTATE_EXIT) {
time_update();
#ifdef _WIN32
double startTime = time_now_d();
UpdateRunLoop();
// Simple throttling to not burn the GPU in the menu.
time_update();
double diffTime = time_now_d() - startTime;
int sleepTime = (int) (1000000.0 / 60.0) - (int) (diffTime * 1000000.0);
if (sleepTime > 0)
Sleep(sleepTime / 1000);
GL_SwapBuffers();
#else
UpdateRunLoop();
#endif
}
while (!coreState) {
time_update();
double startTime = time_now_d();
UpdateScreenScale();
{
{
UpdateRunLoop();
#ifdef _WIN32
lock_guard guard(input_state.lock);
input_state.pad_buttons = 0;
input_state.pad_lstick_x = 0;
input_state.pad_lstick_y = 0;
input_state.pad_rstick_x = 0;
input_state.pad_rstick_y = 0;
host->PollControllers(input_state);
UpdateInputState(&input_state);
#endif
}
NativeUpdate(input_state);
EndInputState(&input_state);
}
NativeRender();
time_update();
// Simple throttling to not burn the GPU in the menu.
#ifdef _WIN32
if (globalUIState != UISTATE_INGAME) {
double diffTime = time_now_d() - startTime;
int sleepTime = (int) (1000000.0 / 60.0) - (int) (diffTime * 1000000.0);
if (sleepTime > 0)
Sleep(sleepTime / 1000);
GL_SwapBuffers();
} else if (!Core_IsStepping()) {
if (!Core_IsStepping()) {
GL_SwapBuffers();
}
#endif
@ -194,6 +208,18 @@ void Core_Run()
#endif
{
reswitch:
if (globalUIState != UISTATE_INGAME) {
if (coreStatePending) {
coreStatePending = false;
m_hInactiveEvent.notify_one();
}
if (globalUIState == UISTATE_EXIT) {
return;
}
Core_RunLoop();
continue;
}
switch (coreState)
{
case CORE_RUNNING:

View File

@ -40,7 +40,8 @@ enum GlobalUIState {
extern GlobalUIState globalUIState;
inline static void UpdateUIState(GlobalUIState newState) {
if (globalUIState != newState) {
// Never leave the EXIT state.
if (globalUIState != newState && globalUIState != UISTATE_EXIT) {
globalUIState = newState;
host->UpdateDisassembly();
}

View File

@ -147,7 +147,8 @@ void EmuScreen::sendMessage(const char *message, const char *value) {
if (!strcmp(message, "pause")) {
screenManager()->push(new GamePauseScreen(gamePath_));
} else if (!strcmp(message, "stop")) {
screenManager()->switchScreen(new MainScreen());
// We will push MainScreen in update().
PSP_Shutdown();
} else if (!strcmp(message, "reset")) {
PSP_Shutdown();
std::string resetError;
@ -497,6 +498,7 @@ void EmuScreen::render() {
} else if (coreState == CORE_POWERDOWN) {
ILOG("SELF-POWERDOWN!");
screenManager()->switchScreen(new MainScreen());
invalid_ = true;
}
if (invalid_)

View File

@ -130,11 +130,12 @@ unsigned int WINAPI TheThread(void *)
while (globalUIState != UISTATE_EXIT)
{
Core_Run();
// We're here again, so the game quit. Restart Core_Run() which controls the UI.
// This way they can load a new game.
Core_UpdateState(CORE_RUNNING);
if (!Core_IsActive())
UpdateUIState(UISTATE_MENU);
Core_Run();
}
shutdown:

View File

@ -783,16 +783,7 @@ namespace MainWindow
}
void WaitForCore() {
if (Core_IsStepping()) {
// If the current PC is on a breakpoint, disabling stepping doesn't work without
// explicitly skipping it
CBreakPoints::SetSkipFirst(currentMIPS->pc);
Core_EnableStepping(false);
}
Core_EnableStepping(true);
Core_WaitInactive();
Core_EnableStepping(false);
Core_Stop();
}
void BrowseAndBoot(std::string defaultPath, bool browseDirectory) {