| 461 | } |
| 462 | |
| 463 | int SaveStateManager::restore(int slot) |
| 464 | { |
| 465 | GlobalNative gn; |
| 466 | |
| 467 | if (!stateReady(slot)) |
| 468 | return ESTATE_NOTCOMPLETE; |
| 469 | |
| 470 | ThreadInfo *current_thread = ThreadManager::getCurrentThread(); |
| 471 | MYASSERT(current_thread->state == ThreadInfo::ST_CKPNTHREAD) |
| 472 | ThreadSync::acquireLocks(); |
| 473 | |
| 474 | /* We must close the connection to the sound device. This must be done |
| 475 | * BEFORE suspending threads. |
| 476 | */ |
| 477 | #ifdef __linux__ |
| 478 | AudioPlayerAlsa::close(); |
| 479 | #elif defined(__APPLE__) && defined(__MACH__) |
| 480 | AudioPlayerCoreAudio::close(); |
| 481 | #endif |
| 482 | |
| 483 | /* Perform a series of checks before attempting to restore */ |
| 484 | int ret = Checkpoint::checkRestore(); |
| 485 | if (ret < 0) { |
| 486 | ThreadSync::releaseLocks(); |
| 487 | return ret; |
| 488 | } |
| 489 | |
| 490 | /* We save the alternate stack if the game did set one */ |
| 491 | AltStack::saveStack(); |
| 492 | |
| 493 | /* `restoreInProgress` is set to false first, so that we can suspend threads |
| 494 | * like in SaveStateManager::checkpoint() */ |
| 495 | restoreInProgress = false; |
| 496 | |
| 497 | #ifdef __unix__ |
| 498 | /* Lock the display so we can empty events */ |
| 499 | lockGameDisplays(); |
| 500 | |
| 501 | /* Sync all X server connections. */ |
| 502 | syncGameDisplays(); |
| 503 | #endif |
| 504 | |
| 505 | /* Stop threads that will not be present after state loading */ |
| 506 | terminateThreads(); |
| 507 | |
| 508 | suspendThreads(); |
| 509 | |
| 510 | #ifdef __unix__ |
| 511 | /* Release Xlib locks before loading the restored process image. */ |
| 512 | unlockGameDisplays(); |
| 513 | #endif |
| 514 | |
| 515 | /* Save thread list in reserved memory */ |
| 516 | saveThreadList(); |
| 517 | |
| 518 | restoreInProgress = true; |
| 519 | |
| 520 | #ifdef __linux__ |
nothing calls this directly
no test coverage detected