startup_checks: Implement unix side code

Wow fork() is nice, isn't it?
master
lat9nq 2022-07-10 17:01:37 +07:00
parent 33abdfff9b
commit fd4e48f96e
2 changed files with 48 additions and 17 deletions

@ -3852,19 +3852,9 @@ void GMainWindow::SetDiscordEnabled([[maybe_unused]] bool state) {
int main(int argc, char* argv[]) {
bool has_broken_vulkan = false;
#ifdef _WIN32
char variable_contents[32];
const DWORD startup_check_var =
GetEnvironmentVariable(STARTUP_CHECK_ENV_VAR, variable_contents, 32);
const std::string variable_contents_s{variable_contents};
if (startup_check_var > 0 && variable_contents_s == "ON") {
CheckVulkan();
if (StartupChecks(argv[0], &has_broken_vulkan)) {
return 0;
}
StartupChecks(argv[0], &has_broken_vulkan);
#elif YUZU_UNIX
#error "Unimplemented"
#endif
Common::DetachedTasks detached_tasks;
MicroProfileOnThreadCreate("Frontend");

@ -8,6 +8,8 @@
#include <processthreadsapi.h>
#include <windows.h>
#elif defined(YUZU_UNIX)
#include <errno.h>
#include <sys/wait.h>
#include <unistd.h>
#endif
@ -36,9 +38,20 @@ void CheckVulkan() {
bool StartupChecks(const char* arg0, bool* has_broken_vulkan) {
#ifdef _WIN32
// Check environment variable to see if we are the child
char variable_contents[32];
const DWORD startup_check_var =
GetEnvironmentVariable(STARTUP_CHECK_ENV_VAR, variable_contents, 32);
const std::string variable_contents_s{variable_contents};
if (startup_check_var > 0 && variable_contents_s == "ON") {
CheckVulkan();
return true;
}
// Set the startup variable for child processes
const bool env_var_set = SetEnvironmentVariableA(STARTUP_CHECK_ENV_VAR, "ON");
if (!env_var_set) {
std::fprintf(stderr, "SetEnvironmentVariableA failed to set %s, %d\n",
std::fprintf(stderr, "SetEnvironmentVariableA failed to set %s with error %d\n",
STARTUP_CHECK_ENV_VAR, GetLastError());
return false;
}
@ -53,15 +66,43 @@ bool StartupChecks(const char* arg0, bool* has_broken_vulkan) {
// wait until the processs exits
DWORD exit_code = STILL_ACTIVE;
while (exit_code == STILL_ACTIVE) {
GetExitCodeProcess(process_info.hProcess, &exit_code);
const int err = GetExitCodeProcess(process_info.hProcess, &exit_code);
if (err == 0) {
std::fprintf(stderr, "GetExitCodeProcess failed with error %d\n", GetLastError());
break;
}
}
*has_broken_vulkan = (exit_code != 0);
CloseHandle(process_info.hProcess);
CloseHandle(process_info.hThread);
if (CloseHandle(process_info.hProcess) == 0) {
std::fprintf(stderr, "CloseHandle failed with error %d\n", GetLastError());
}
if (CloseHandle(process_info.hThread) == 0) {
std::fprintf(stderr, "CloseHandle failed with error %d\n", GetLastError());
}
#elif defined(YUZU_UNIX)
const pid_t pid = fork();
if (pid == 0) {
CheckVulkan();
return true;
} else if (pid == -1) {
const int err = errno;
std::fprintf(stderr, "fork failed with error %d\n", err);
return false;
}
int status;
const int r_val = wait(&status);
if (r_val == -1) {
const int err = errno;
std::fprintf(stderr, "wait failed with error %d\n", err);
return false;
}
*has_broken_vulkan = (status != 0);
#endif
return true;
return false;
}
#ifdef _WIN32
@ -87,7 +128,7 @@ bool SpawnChild(const char* arg0, PROCESS_INFORMATION* pi) {
pi // lpProcessInformation
);
if (!process_created) {
std::fprintf(stderr, "CreateProcessA failed, %d\n", GetLastError());
std::fprintf(stderr, "CreateProcessA failed with error %d\n", GetLastError());
return false;
}