Skip to content

Commit

Permalink
feat: add global thread pauser API
Browse files Browse the repository at this point in the history
  • Loading branch information
OEOTYAN committed Nov 24, 2023
1 parent 50d3193 commit 936fc71
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 35 deletions.
6 changes: 3 additions & 3 deletions src/ll/api/Logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void Logger::OutputStream::print(std::string_view s) const noexcept {
if (!ll::globalConfig.logger.colorLog) {
str = removeEscapeCode(str);
}
fmt::print("{}\r\n", str);
fmt::print("{}\n", str);
}
if (logger->getFile().is_open() && checkLogLevel(logger->fileLevel, level)) {
logger->getFile() << removeEscapeCode(fmt::format(
Expand Down Expand Up @@ -65,12 +65,12 @@ void Logger::OutputStream::print(std::string_view s) const noexcept {
} catch (...) {
try {
fmt::print(
"\x1b[31mERROR IN LOGGER API:\r\n{}\x1b[0m\r\n",
"\x1b[31mERROR IN LOGGER API:\n{}\x1b[0m\n",
error_info::makeExceptionString(std::current_exception())
);
} catch (...) {
try {
fmt::print("\x1b[31mUNKNOWN ERROR IN LOGGER API\x1b[0m\r\n");
fmt::print("\x1b[31mUNKNOWN ERROR IN LOGGER API\x1b[0m\n");
} catch (...) {}
}
}
Expand Down
43 changes: 24 additions & 19 deletions src/ll/api/base/ErrorInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ struct u8system_category : public std::_System_error_category {
std::string res{string_utils::str2str({msg._Str, msg._Length})};
if (res.ends_with('\n')) {
res.pop_back();
}
if (res.ends_with('\r')) {
res.pop_back();
if (res.ends_with('\r')) {
res.pop_back();
}
}
return string_utils::replaceAll(res, "\r\n", ", ");
}
Expand All @@ -51,20 +51,25 @@ std::error_category const& u8system_category() noexcept {
struct ntstatus_category : public std::error_category {
constexpr ntstatus_category() noexcept : error_category() {}
[[nodiscard]] std::string message(int errCode) const override {
wchar_t* msg = nullptr;
DWORD langId;
if (GetLocaleInfoEx(
LOCALE_NAME_SYSTEM_DEFAULT,
LOCALE_SNAME | LOCALE_RETURN_NUMBER,
reinterpret_cast<LPWSTR>(&langId),
sizeof(langId) / sizeof(wchar_t)
)
== 0) {
langId = 0;
}
auto size = FormatMessageW(
static DWORD langId = [] {
DWORD res;
if (GetLocaleInfoEx(
LOCALE_NAME_SYSTEM_DEFAULT,
LOCALE_SNAME | LOCALE_RETURN_NUMBER,
reinterpret_cast<LPWSTR>(&res),
sizeof(res) / sizeof(wchar_t)
)
== 0) {
res = 0;
}
return res;
}();
static auto nt = GetModuleHandleW(L"ntdll");

wchar_t* msg = nullptr;
auto size = FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS,
GetModuleHandleW(L"ntdll"),
nt,
errCode,
langId,
(wchar_t*)&msg,
Expand All @@ -76,9 +81,9 @@ struct ntstatus_category : public std::error_category {
LocalFree(msg);
if (res.ends_with('\n')) {
res.pop_back();
}
if (res.ends_with('\r')) {
res.pop_back();
if (res.ends_with('\r')) {
res.pop_back();
}
}
return string_utils::replaceAll(res, "\r\n", ", ");
}
Expand Down
8 changes: 7 additions & 1 deletion src/ll/api/memory/Hook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@

#include "ll/api/memory/Memory.h"

#include "ll/api/thread/GlobalThreadPauser.h"

namespace ll::memory {

int hook(FuncPtr target, FuncPtr detour, FuncPtr* originalFunc, HookPriority priority) {
auto pause = ll::thread::GlobalThreadPauser{};
return pl::hook::pl_hook(target, detour, originalFunc, static_cast<pl::hook::Priority>(priority));
}

bool unhook(FuncPtr target, FuncPtr detour) { return pl::hook::pl_unhook(target, detour); }
bool unhook(FuncPtr target, FuncPtr detour) {
auto pause = ll::thread::GlobalThreadPauser{};
return pl::hook::pl_unhook(target, detour);
}

FuncPtr resolveIdentifier(char const* identifier) {
auto p = resolveSymbol(identifier);
Expand Down
10 changes: 5 additions & 5 deletions src/ll/api/memory/Hook.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,22 @@
try { \
static FuncPtr t = ll::memory::resolveIdentifier<OriginFuncType>(IDENTIFIER); \
if (t == nullptr) { \
fmt::print("\x1b[91mCan't resolve: [" #IDENTIFIER "]\x1b[0m\r\n"); \
fmt::print("\x1b[91mCan't resolve: [" #IDENTIFIER "]\x1b[0m\n"); \
} else { \
auto symbols = ll::memory::lookupSymbol(t); \
if (symbols.size() > 1) { \
fmt::print( \
"\x1b[93m[" #IDENTIFIER "] has {} matches, probability cause bugs.\x1b[0m\r\n", \
"\x1b[93m[" #IDENTIFIER "] has {} matches, probability cause bugs.\x1b[0m\n", \
symbols.size() \
); \
} \
fmt::print("\x1b[96m v resolve [" #IDENTIFIER "] to:\x1b[0m\r\n"); \
fmt::print("\x1b[96m v resolve [" #IDENTIFIER "] to:\x1b[0m\n"); \
for (auto& str : symbols) { \
fmt::print(" {} {}\r\n", (&str == &symbols.back()) ? '-' : '|', str); \
fmt::print(" {} {}\n", (&str == &symbols.back()) ? '-' : '|', str); \
} \
} \
} catch (...) { \
fmt::print("\x1b[91m!!! Exception in resolve: [" #IDENTIFIER "]\x1b[0m\r\n"); \
fmt::print("\x1b[91m!!! Exception in resolve: [" #IDENTIFIER "]\x1b[0m\n"); \
} \
return 0; \
}; \
Expand Down
14 changes: 7 additions & 7 deletions src/ll/api/schedule/Scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,27 @@ struct SleeperType<ll::chrono::GameTimeClock> {
using Type = ll::chrono::TickSyncSleep<ll::chrono::GameTimeClock>;
};

template <class Clock, class Sleeper = SleeperType<Clock>::Type>
template <class Clock, class Sleeper = SleeperType<Clock>::Type, class Pool = ll::thread::ThreadPool>
class Scheduler;

using GameTickScheduler = Scheduler<ll::chrono::ServerClock>;
using GameTimeScheduler = Scheduler<ll::chrono::GameTimeClock>;

using SystemTimeScheduler = Scheduler<std::chrono::system_clock>;

template <class Clock, class Sleeper>
template <class Clock, class Sleeper, class Pool>
class Scheduler {
private:
using TimePoint = typename Clock::time_point;
using Duration = typename Clock::duration;
using TaskPtr = std::shared_ptr<Task<Clock>>;
using TaskType = std::multimap<TimePoint, TaskPtr>;

TaskType tasks;
std::atomic<bool> done;
std::mutex mutex;
Sleeper sleeper;
ll::thread::ThreadPool threads;
TaskType tasks;
std::atomic<bool> done;
std::mutex mutex;
Sleeper sleeper;
Pool threads;

std::weak_ptr<Task<Clock>> addTask(TaskPtr t) {
std::weak_ptr<Task<Clock>> res = t;
Expand Down
48 changes: 48 additions & 0 deletions src/ll/api/thread/GlobalThreadPauser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include "ll/api/thread/GlobalThreadPauser.h"

#include "ll/api/base/ErrorInfo.h"

#include "windows.h"

#include "tlhelp32.h"

namespace ll::thread {
GlobalThreadPauser::GlobalThreadPauser() {
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (h == INVALID_HANDLE_VALUE) {
throw error_info::getWinLastError();
}
static auto processId = GetCurrentProcessId();
auto threadId = GetCurrentThreadId();

THREADENTRY32 te;
te.dwSize = sizeof(te);
if (Thread32First(h, &te)) {
do {
if (te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(te.th32OwnerProcessID)) {
// Suspend all threads EXCEPT the one we want to keep running
if (te.th32OwnerProcessID == processId && te.th32ThreadID != threadId) {
HANDLE thread = OpenThread(THREAD_ALL_ACCESS, false, te.th32ThreadID);
if (thread != nullptr) {
SuspendThread(thread);
CloseHandle(thread);
pausedIds.emplace_back(te.th32ThreadID);
}
}
}
te.dwSize = sizeof(te);
} while (Thread32Next(h, &te));
}
CloseHandle(h);
}
GlobalThreadPauser::~GlobalThreadPauser() {
for (auto id : pausedIds) {
HANDLE thread = OpenThread(THREAD_ALL_ACCESS, false, id);
if (thread != nullptr) {
ResumeThread(thread);
CloseHandle(thread);
}
}
}

} // namespace ll::thread
15 changes: 15 additions & 0 deletions src/ll/api/thread/GlobalThreadPauser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include "ll/api/base/Macro.h"
#include "ll/api/base/StdInt.h"
#include <vector>

namespace ll::thread {
class GlobalThreadPauser {
std::vector<uint> pausedIds;

public:
LLNDAPI GlobalThreadPauser();
LLNDAPI ~GlobalThreadPauser();
};
} // namespace ll::thread
3 changes: 3 additions & 0 deletions src/ll/core/form/FormHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ LL_AUTO_TYPED_INSTANCE_HOOK(
data = modalPacket.mJSONResponse.value().toStyledString();
if (data.ends_with('\n')) {
data.pop_back();
if (data.ends_with('\r')) {
data.pop_back();
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/ll/core/tweak/ModifyInfomation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ LL_AUTO_STATIC_HOOK(
while (std::getline(iss, line)) {
if (line.ends_with('\n')) {
line.pop_back();
if (line.ends_with('\r')) {
line.pop_back();
}
}

if (!serverStarted) tryModifyServerStartInfo(line);
Expand Down
15 changes: 15 additions & 0 deletions src/ll/test/ScheduleTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "mc/server/ServerLevel.h"
#include "mc/world/events/ServerInstanceEventCoordinator.h"

// #include "ll/api/thread/GlobalThreadPauser.h"

using namespace ll::schedule;

using namespace ll::chrono_literals;
Expand Down Expand Up @@ -65,6 +67,19 @@ LL_AUTO_TYPED_INSTANCE_HOOK(
throw std::runtime_error("I'm a error from schedule Task!");
});

// s2.add<RepeatTask>(0.3min, [&] {
// auto pause = ll::thread::GlobalThreadPauser{};

// schedulelogger.info("hello I paused all threads 1s");

// std::this_thread::sleep_for(1s);
// schedulelogger.info("hello I paused all threads 2s");

// std::this_thread::sleep_for(1s);

// schedulelogger.info("hello I resumed all threads");
// });

return origin(ins);
}

Expand Down

0 comments on commit 936fc71

Please sign in to comment.