fix shared memory reboot loss
This commit is contained in:
parent
7fca148bc6
commit
b20a970b1d
|
@ -577,6 +577,26 @@ XBSYSAPI EXPORTNUM(49) xboxkrnl::VOID DECLSPEC_NORETURN NTAPI xboxkrnl::HalRetur
|
||||||
if (!CxbxExec(false, nullptr, false)) {
|
if (!CxbxExec(false, nullptr, false)) {
|
||||||
CxbxKrnlCleanup("Could not launch %s", XbePath.c_str());
|
CxbxKrnlCleanup("Could not launch %s", XbePath.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a requirement to have shared memory buffers remain alive and transfer to new emulation process.
|
||||||
|
unsigned int retryAttempt = 0;
|
||||||
|
unsigned int curProcID = 0;
|
||||||
|
unsigned int oldProcID = GetCurrentProcessId();
|
||||||
|
while(true) {
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
g_EmuShared->GetKrnlProcID(&curProcID);
|
||||||
|
// Break when new emulation process has take over.
|
||||||
|
if (curProcID != oldProcID) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
retryAttempt++;
|
||||||
|
// Terminate after 5 seconds of failure.
|
||||||
|
if (retryAttempt >= (5 * (1000 / 100))) {
|
||||||
|
CxbxShowError("Could not reboot, new emulation process did not take over.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -752,11 +752,6 @@ void CxbxKrnlEmulate(uint32_t blocks_reserved[384])
|
||||||
/* Initialize Cxbx File Paths */
|
/* Initialize Cxbx File Paths */
|
||||||
CxbxInitFilePaths();
|
CxbxInitFilePaths();
|
||||||
|
|
||||||
/* Must be called after CxbxInitFilePaths */
|
|
||||||
if (!CxbxLockFilePath()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip '/load' switch
|
// Skip '/load' switch
|
||||||
// Get XBE Name :
|
// Get XBE Name :
|
||||||
std::string xbePath;
|
std::string xbePath;
|
||||||
|
@ -784,44 +779,8 @@ void CxbxKrnlEmulate(uint32_t blocks_reserved[384])
|
||||||
}
|
}
|
||||||
|
|
||||||
int BootFlags;
|
int BootFlags;
|
||||||
FILE* krnlLog = nullptr;
|
|
||||||
g_EmuShared->GetBootFlags(&BootFlags);
|
g_EmuShared->GetBootFlags(&BootFlags);
|
||||||
|
|
||||||
// debug console allocation (if configured)
|
|
||||||
if (DbgMode == DM_CONSOLE)
|
|
||||||
{
|
|
||||||
if (AllocConsole())
|
|
||||||
{
|
|
||||||
HANDLE StdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
||||||
// Maximise the console scroll buffer height :
|
|
||||||
CONSOLE_SCREEN_BUFFER_INFO coninfo;
|
|
||||||
GetConsoleScreenBufferInfo(StdHandle, &coninfo);
|
|
||||||
coninfo.dwSize.Y = SHRT_MAX - 1; // = 32767-1 = 32766 = maximum value that works
|
|
||||||
SetConsoleScreenBufferSize(StdHandle, coninfo.dwSize);
|
|
||||||
(void)freopen("CONOUT$", "wt", stdout);
|
|
||||||
(void)freopen("CONIN$", "rt", stdin);
|
|
||||||
SetConsoleTitle("Cxbx-Reloaded : Kernel Debug Console");
|
|
||||||
SetConsoleTextAttribute(StdHandle, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FreeConsole();
|
|
||||||
if (DbgMode == DM_FILE) {
|
|
||||||
// Peform clean write to kernel log for first boot. Unless multi-xbe boot occur then perform append to existing log.
|
|
||||||
krnlLog = freopen(DebugFileName.c_str(), ((BootFlags == DebugMode::DM_NONE) ? "wt" : "at"), stdout);
|
|
||||||
// Append separator for better readability after reboot.
|
|
||||||
if (BootFlags != DebugMode::DM_NONE) {
|
|
||||||
std::cout << "\n------REBOOT------REBOOT------REBOOT------REBOOT------REBOOT------\n" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
char buffer[16];
|
|
||||||
if (GetConsoleTitle(buffer, 16) != NULL)
|
|
||||||
(void)freopen("nul", "w", stdout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_CurrentProcessHandle = GetCurrentProcess(); // OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
|
g_CurrentProcessHandle = GetCurrentProcess(); // OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
|
||||||
|
|
||||||
// Set up the logging variables for the kernel process during initialization.
|
// Set up the logging variables for the kernel process during initialization.
|
||||||
|
@ -862,6 +821,10 @@ void CxbxKrnlEmulate(uint32_t blocks_reserved[384])
|
||||||
DWORD dwExitCode = EXIT_SUCCESS;
|
DWORD dwExitCode = EXIT_SUCCESS;
|
||||||
g_EmuShared->GetKrnlProcID(&prevKrnlProcID);
|
g_EmuShared->GetKrnlProcID(&prevKrnlProcID);
|
||||||
|
|
||||||
|
// Save current kernel proccess id for next reboot if will occur in the future.
|
||||||
|
// And to tell previous kernel process we had take over. This allow reboot's shared memory buffer to survive.
|
||||||
|
g_EmuShared->SetKrnlProcID(GetCurrentProcessId());
|
||||||
|
|
||||||
// Force wait until previous kernel process is closed.
|
// Force wait until previous kernel process is closed.
|
||||||
if (prevKrnlProcID != 0) {
|
if (prevKrnlProcID != 0) {
|
||||||
HANDLE hProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE, prevKrnlProcID);
|
HANDLE hProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE, prevKrnlProcID);
|
||||||
|
@ -879,15 +842,53 @@ void CxbxKrnlEmulate(uint32_t blocks_reserved[384])
|
||||||
CxbxKrnlShutDown();
|
CxbxKrnlShutDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Must be called after CxbxInitFilePaths and previous kernel process shutdown. */
|
||||||
|
if (!CxbxLockFilePath()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* krnlLog = nullptr;
|
||||||
|
// debug console allocation (if configured)
|
||||||
|
if (DbgMode == DM_CONSOLE)
|
||||||
|
{
|
||||||
|
if (AllocConsole())
|
||||||
|
{
|
||||||
|
HANDLE StdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
// Maximise the console scroll buffer height :
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO coninfo;
|
||||||
|
GetConsoleScreenBufferInfo(StdHandle, &coninfo);
|
||||||
|
coninfo.dwSize.Y = SHRT_MAX - 1; // = 32767-1 = 32766 = maximum value that works
|
||||||
|
SetConsoleScreenBufferSize(StdHandle, coninfo.dwSize);
|
||||||
|
(void)freopen("CONOUT$", "wt", stdout);
|
||||||
|
(void)freopen("CONIN$", "rt", stdin);
|
||||||
|
SetConsoleTitle("Cxbx-Reloaded : Kernel Debug Console");
|
||||||
|
SetConsoleTextAttribute(StdHandle, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FreeConsole();
|
||||||
|
if (DbgMode == DM_FILE) {
|
||||||
|
// Peform clean write to kernel log for first boot. Unless multi-xbe boot occur then perform append to existing log.
|
||||||
|
krnlLog = freopen(DebugFileName.c_str(), ((BootFlags == DebugMode::DM_NONE) ? "wt" : "at"), stdout);
|
||||||
|
// Append separator for better readability after reboot.
|
||||||
|
if (BootFlags != DebugMode::DM_NONE) {
|
||||||
|
std::cout << "\n------REBOOT------REBOOT------REBOOT------REBOOT------REBOOT------\n" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
char buffer[16];
|
||||||
|
if (GetConsoleTitle(buffer, 16) != NULL)
|
||||||
|
(void)freopen("nul", "w", stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool isLogEnabled;
|
bool isLogEnabled;
|
||||||
g_EmuShared->GetIsKrnlLogEnabled(&isLogEnabled);
|
g_EmuShared->GetIsKrnlLogEnabled(&isLogEnabled);
|
||||||
g_bPrintfOn = isLogEnabled;
|
g_bPrintfOn = isLogEnabled;
|
||||||
|
|
||||||
g_EmuShared->ResetKrnl();
|
g_EmuShared->ResetKrnl();
|
||||||
|
|
||||||
// Save current kernel proccess id for next reboot if will occur in the future.
|
|
||||||
g_EmuShared->SetKrnlProcID(GetCurrentProcessId());
|
|
||||||
|
|
||||||
// Write a header to the log
|
// Write a header to the log
|
||||||
{
|
{
|
||||||
EmuLogInit(LOG_LEVEL::INFO, "Cxbx-Reloaded Version %s", CxbxVersionStr);
|
EmuLogInit(LOG_LEVEL::INFO, "Cxbx-Reloaded Version %s", CxbxVersionStr);
|
||||||
|
|
Loading…
Reference in New Issue