mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-23 05:31:03 +00:00
Dump emulation state in analyzer (#168)
This commit is contained in:
88
src/common/utils/interupt_handler.cpp
Normal file
88
src/common/utils/interupt_handler.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
#include "interupt_handler.hpp"
|
||||
#include <atomic>
|
||||
#include <stdexcept>
|
||||
#include <thread>
|
||||
|
||||
#include "win.hpp"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <csignal>
|
||||
#endif
|
||||
|
||||
namespace utils
|
||||
{
|
||||
namespace
|
||||
{
|
||||
struct signal_data
|
||||
{
|
||||
std::atomic_bool installed{false};
|
||||
std::function<void()> handler{};
|
||||
};
|
||||
|
||||
signal_data& get_signal_data()
|
||||
{
|
||||
static signal_data data{};
|
||||
return data;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
BOOL WINAPI handler(const DWORD signal)
|
||||
{
|
||||
const auto& data = get_signal_data();
|
||||
|
||||
if (signal == CTRL_C_EVENT && data.handler)
|
||||
{
|
||||
data.handler();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#else
|
||||
void handler(int signal)
|
||||
{
|
||||
const auto& data = get_signal_data();
|
||||
|
||||
if (signal == SIGINT && data.handler)
|
||||
{
|
||||
data.handler();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
interupt_handler::interupt_handler(std::function<void()> callback)
|
||||
{
|
||||
auto& data = get_signal_data();
|
||||
|
||||
bool value{false};
|
||||
if (!data.installed.compare_exchange_strong(value, true))
|
||||
{
|
||||
throw std::runtime_error("Global signal handler already installed");
|
||||
}
|
||||
|
||||
data.handler = std::move(callback);
|
||||
|
||||
#ifdef _WIN32
|
||||
SetConsoleCtrlHandler(handler, TRUE);
|
||||
#else
|
||||
signal(SIGINT, handler);
|
||||
#endif
|
||||
}
|
||||
|
||||
interupt_handler::~interupt_handler()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
SetConsoleCtrlHandler(handler, FALSE);
|
||||
#else
|
||||
signal(SIGINT, SIG_DFL);
|
||||
#endif
|
||||
|
||||
std::this_thread::yield();
|
||||
|
||||
auto& data = get_signal_data();
|
||||
|
||||
data.handler = {};
|
||||
data.installed = false;
|
||||
}
|
||||
}
|
||||
17
src/common/utils/interupt_handler.hpp
Normal file
17
src/common/utils/interupt_handler.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include <functional>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
struct interupt_handler
|
||||
{
|
||||
interupt_handler(std::function<void()> callback);
|
||||
~interupt_handler();
|
||||
|
||||
interupt_handler(interupt_handler&&) = delete;
|
||||
interupt_handler(const interupt_handler&) = delete;
|
||||
|
||||
interupt_handler& operator=(interupt_handler&&) = delete;
|
||||
interupt_handler& operator=(const interupt_handler&) = delete;
|
||||
};
|
||||
}
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
#define NOMINMAX
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include "win.hpp"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
23
src/common/utils/win.hpp
Normal file
23
src/common/utils/win.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#ifndef _CRT_NO_POSIX_ERROR_CODES
|
||||
#define _CRT_NO_POSIX_ERROR_CODES
|
||||
#endif
|
||||
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user