forked from Public-Mirror/Textractor
use thread pooling and remove text thread cap
This commit is contained in:
parent
de109d0840
commit
dca006b28c
@ -102,12 +102,7 @@ namespace
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
auto tp = *(ThreadParam*)buffer;
|
auto tp = *(ThreadParam*)buffer;
|
||||||
if (textThreadsByParams->count(tp) == 0)
|
if (textThreadsByParams->count(tp) == 0) textThreadsByParams->insert({ tp, std::make_shared<TextThread>(tp, Host::GetHookParam(tp)) });
|
||||||
{
|
|
||||||
auto textThread = textThreadsByParams->insert({ tp, std::make_shared<TextThread>(tp, Host::GetHookParam(tp)) }).first->second;
|
|
||||||
if (textThreadsByParams->size() < MAX_THREAD_COUNT) textThread->Start();
|
|
||||||
else Host::AddConsoleOutput(TOO_MANY_THREADS);
|
|
||||||
}
|
|
||||||
textThreadsByParams->at(tp)->Push(buffer + sizeof(tp), bytesRead - sizeof(tp));
|
textThreadsByParams->at(tp)->Push(buffer + sizeof(tp), bytesRead - sizeof(tp));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -8,19 +8,18 @@ TextThread::TextThread(ThreadParam tp, HookParam hp, std::optional<std::wstring>
|
|||||||
handle(threadCounter++),
|
handle(threadCounter++),
|
||||||
name(name.value_or(Util::StringToWideString(hp.name).value())),
|
name(name.value_or(Util::StringToWideString(hp.name).value())),
|
||||||
tp(tp),
|
tp(tp),
|
||||||
hp(hp)
|
hp(hp),
|
||||||
|
timer(NULL)
|
||||||
{
|
{
|
||||||
|
HANDLE newTimer;
|
||||||
|
CreateTimerQueueTimer(&newTimer, NULL, Flush, this, 25, 25, WT_EXECUTELONGFUNCTION);
|
||||||
|
timer = newTimer;
|
||||||
OnCreate(this);
|
OnCreate(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextThread::~TextThread()
|
TextThread::~TextThread()
|
||||||
{
|
{
|
||||||
if (flushThread.joinable())
|
OnDestroy(this);
|
||||||
{
|
|
||||||
SetEvent(deletionEvent);
|
|
||||||
flushThread.join();
|
|
||||||
OnDestroy(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstring TextThread::GetStorage()
|
std::wstring TextThread::GetStorage()
|
||||||
@ -28,12 +27,6 @@ std::wstring TextThread::GetStorage()
|
|||||||
return storage->c_str();
|
return storage->c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextThread::Start()
|
|
||||||
{
|
|
||||||
deletionEvent = CreateEventW(nullptr, FALSE, FALSE, NULL);
|
|
||||||
flushThread = std::thread([&] { while (WaitForSingleObject(deletionEvent, 10) == WAIT_TIMEOUT) Flush(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextThread::AddSentence(std::wstring sentence)
|
void TextThread::AddSentence(std::wstring sentence)
|
||||||
{
|
{
|
||||||
if (Output(this, sentence)) storage->append(sentence);
|
if (Output(this, sentence)) storage->append(sentence);
|
||||||
@ -41,7 +34,7 @@ void TextThread::AddSentence(std::wstring sentence)
|
|||||||
|
|
||||||
void TextThread::Push(const BYTE* data, int len)
|
void TextThread::Push(const BYTE* data, int len)
|
||||||
{
|
{
|
||||||
if (!flushThread.joinable() || len < 0) return;
|
if (len < 0) return;
|
||||||
LOCK(bufferMutex);
|
LOCK(bufferMutex);
|
||||||
if (hp.type & USING_UNICODE) buffer += std::wstring((wchar_t*)data, len / 2);
|
if (hp.type & USING_UNICODE) buffer += std::wstring((wchar_t*)data, len / 2);
|
||||||
else if (auto converted = Util::StringToWideString(std::string((char*)data, len), hp.codepage ? hp.codepage : defaultCodepage)) buffer += converted.value();
|
else if (auto converted = Util::StringToWideString(std::string((char*)data, len), hp.codepage ? hp.codepage : defaultCodepage)) buffer += converted.value();
|
||||||
@ -50,18 +43,19 @@ void TextThread::Push(const BYTE* data, int len)
|
|||||||
lastPushTime = GetTickCount();
|
lastPushTime = GetTickCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextThread::Flush()
|
void CALLBACK Flush(void* thread, BOOLEAN)
|
||||||
{
|
{
|
||||||
|
auto This = (TextThread*)thread;
|
||||||
std::wstring sentence;
|
std::wstring sentence;
|
||||||
{
|
{
|
||||||
LOCK(bufferMutex);
|
LOCK(This->bufferMutex);
|
||||||
if (buffer.empty()) return;
|
if (This->buffer.empty()) return;
|
||||||
if (buffer.size() < maxBufferSize && GetTickCount() - lastPushTime < flushDelay) return;
|
if (This->buffer.size() < This->maxBufferSize && GetTickCount() - This->lastPushTime < This->flushDelay) return;
|
||||||
sentence = buffer;
|
sentence = This->buffer;
|
||||||
buffer.clear();
|
This->buffer.clear();
|
||||||
|
|
||||||
if (Util::RemoveRepetition(sentence)) repeatingChars = std::unordered_set(sentence.begin(), sentence.end());
|
if (Util::RemoveRepetition(sentence)) This->repeatingChars = std::unordered_set(sentence.begin(), sentence.end());
|
||||||
else repeatingChars.clear();
|
else This->repeatingChars.clear();
|
||||||
}
|
}
|
||||||
AddSentence(sentence);
|
This->AddSentence(sentence);
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,9 @@ public:
|
|||||||
~TextThread();
|
~TextThread();
|
||||||
|
|
||||||
std::wstring GetStorage();
|
std::wstring GetStorage();
|
||||||
void Start();
|
|
||||||
void AddSentence(std::wstring sentence);
|
void AddSentence(std::wstring sentence);
|
||||||
void Push(const BYTE* data, int len);
|
void Push(const BYTE* data, int len);
|
||||||
|
friend void CALLBACK Flush(void* thread, BOOLEAN);
|
||||||
|
|
||||||
const int64_t handle;
|
const int64_t handle;
|
||||||
const std::wstring name;
|
const std::wstring name;
|
||||||
@ -30,13 +30,12 @@ public:
|
|||||||
const HookParam hp;
|
const HookParam hp;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Flush();
|
struct TimerDeleter { void operator()(void* h) { DeleteTimerQueueTimer(NULL, h, INVALID_HANDLE_VALUE); } };
|
||||||
|
|
||||||
ThreadSafePtr<std::wstring> storage;
|
ThreadSafePtr<std::wstring> storage;
|
||||||
std::wstring buffer;
|
std::wstring buffer;
|
||||||
std::unordered_set<wchar_t> repeatingChars;
|
std::unordered_set<wchar_t> repeatingChars;
|
||||||
std::mutex bufferMutex;
|
std::mutex bufferMutex;
|
||||||
AutoHandle<> deletionEvent = NULL;
|
AutoHandle<TimerDeleter> timer;
|
||||||
std::thread flushThread;
|
|
||||||
DWORD lastPushTime;
|
DWORD lastPushTime;
|
||||||
};
|
};
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
// 8/23/2013 jichi
|
// 8/23/2013 jichi
|
||||||
// Branch: ITH/common.h, rev 128
|
// Branch: ITH/common.h, rev 128
|
||||||
|
|
||||||
enum { MESSAGE_SIZE = 500, PIPE_BUFFER_SIZE = 2000, SHIFT_JIS = 932, MAX_THREAD_COUNT = 250, MAX_MODULE_SIZE = 120, HOOK_NAME_SIZE = 30 };
|
enum { MESSAGE_SIZE = 500, PIPE_BUFFER_SIZE = 2000, SHIFT_JIS = 932, MAX_MODULE_SIZE = 120, HOOK_NAME_SIZE = 30 };
|
||||||
|
|
||||||
// jichi 375/2014: Add offset of pusha/pushad
|
// jichi 375/2014: Add offset of pusha/pushad
|
||||||
// http://faydoc.tripod.com/cpu/pushad.htm
|
// http://faydoc.tripod.com/cpu/pushad.htm
|
||||||
|
@ -25,7 +25,6 @@ constexpr auto ABOUT = L"Textractor beta v3.5.0 (project homepage: https://githu
|
|||||||
"Please contact Artikash with any problems, feature requests, or questions relating to Textractor\r\n"
|
"Please contact Artikash with any problems, feature requests, or questions relating to Textractor\r\n"
|
||||||
"You can do so via the project homepage (issues section) or via email\r\n"
|
"You can do so via the project homepage (issues section) or via email\r\n"
|
||||||
"Source code available under GPLv3 at project homepage";
|
"Source code available under GPLv3 at project homepage";
|
||||||
constexpr auto TOO_MANY_THREADS = L"Textractor: too many text threads: can't create more";
|
|
||||||
constexpr auto ALREADY_INJECTED = L"Textractor: already injected";
|
constexpr auto ALREADY_INJECTED = L"Textractor: already injected";
|
||||||
constexpr auto ARCHITECTURE_MISMATCH = L"Textractor: architecture mismatch: try 32 bit Textractor instead";
|
constexpr auto ARCHITECTURE_MISMATCH = L"Textractor: architecture mismatch: try 32 bit Textractor instead";
|
||||||
constexpr auto INJECT_FAILED = L"Textractor: couldn't inject";
|
constexpr auto INJECT_FAILED = L"Textractor: couldn't inject";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user