diff --git a/GUI/host/host.cc b/GUI/host/host.cc index ff9c3b8..6daa845 100644 --- a/GUI/host/host.cc +++ b/GUI/host/host.cc @@ -35,7 +35,9 @@ namespace LOCK(hostMutex); TextThread *it; if ((it = textThreadsByParams[tp]) == nullptr) - OnCreate(it = textThreadsByParams[tp] = new TextThread(tp, Host::GetHookParam(tp).type)); + if (TextThread::ThreadCounter < MAX_THREAD_COUNT) + OnCreate(it = textThreadsByParams[tp] = new TextThread(tp, Host::GetHookParam(tp).type)); + else return Host::AddConsoleOutput(L"too many text threads: stopping"); it->AddText(text, len); } diff --git a/GUI/host/host.h b/GUI/host/host.h index 56e9a8e..79d08e0 100644 --- a/GUI/host/host.h +++ b/GUI/host/host.h @@ -32,7 +32,7 @@ namespace Host inline std::wstring StringToWideString(const std::string& text, UINT encoding) { std::wstring ret(text.size() + 1, 0); - ret.resize(MultiByteToWideChar(encoding, 0, text.c_str(), -1, ret.data(), ret.capacity())); + ret.resize(MultiByteToWideChar(encoding, 0, text.c_str(), -1, ret.data(), ret.capacity()) - 1); return ret; } diff --git a/GUI/host/textthread.cc b/GUI/host/textthread.cc index 531f402..e8d69f5 100644 --- a/GUI/host/textthread.cc +++ b/GUI/host/textthread.cc @@ -10,9 +10,9 @@ TextThread::TextThread(ThreadParam tp, DWORD status) : handle(ThreadCounter++), TextThread::~TextThread() { - SetEvent(cancelFlushEvent); - flusher.join(); - CloseHandle(cancelFlushEvent); + SetEvent(deletionEvent); + flushThread.join(); + CloseHandle(deletionEvent); } std::wstring TextThread::GetStore() @@ -26,6 +26,7 @@ void TextThread::Flush() std::wstring sentence; { LOCK(ttMutex); + if (buffer.size() < MaxBufferSize && (GetTickCount() - timestamp < FlushDelay || buffer.size() < 2)) return; sentence = buffer; buffer.clear(); } @@ -42,18 +43,12 @@ void TextThread::AddSentence(std::wstring sentence) void TextThread::AddText(const BYTE* data, int len) { - if (buffer.size() > MaxBufferSize) Flush(); - SetEvent(cancelFlushEvent); - flusher.join(); - flusher = std::thread([&] - { - ResetEvent(cancelFlushEvent); - if (WaitForSingleObject(cancelFlushEvent, FlushDelay) == WAIT_TIMEOUT) Flush(); - }); - LOCK(ttMutex); - buffer += status & USING_UNICODE + std::wstring wData = status & USING_UNICODE ? std::wstring((wchar_t*)data, len / 2) : StringToWideString(std::string((char*)data, len), status & USING_UTF8 ? CP_UTF8 : SHIFT_JIS); + LOCK(ttMutex); + buffer.append(wData); + timestamp = GetTickCount(); } // EOF diff --git a/GUI/host/textthread.h b/GUI/host/textthread.h index bdd3d3e..a806269 100644 --- a/GUI/host/textthread.h +++ b/GUI/host/textthread.h @@ -25,7 +25,7 @@ public: const ThreadParam tp; inline static int FlushDelay = 250; // flush every 250ms by default - inline static int MaxBufferSize = 500; + inline static int MaxBufferSize = 200; inline static int ThreadCounter = 0; private: @@ -34,8 +34,10 @@ private: std::wstring buffer; std::wstring storage; std::recursive_mutex ttMutex; - std::thread flusher = std::thread([] {}); - HANDLE cancelFlushEvent = CreateEventW(nullptr, TRUE, TRUE, NULL); + + HANDLE deletionEvent = CreateEventW(nullptr, FALSE, FALSE, NULL); + std::thread flushThread = std::thread([&] { while (WaitForSingleObject(deletionEvent, 10) == WAIT_TIMEOUT) Flush(); }); + DWORD timestamp = GetTickCount(); ThreadOutputCallback Output; DWORD status; diff --git a/include/const.h b/include/const.h index 144fa52..501be38 100644 --- a/include/const.h +++ b/include/const.h @@ -4,7 +4,7 @@ // 8/23/2013 jichi // Branch: ITH/common.h, rev 128 -enum { MESSAGE_SIZE = 500, PIPE_BUFFER_SIZE = 0x1000, SHIFT_JIS = 932 }; +enum { MESSAGE_SIZE = 500, PIPE_BUFFER_SIZE = 0x1000, SHIFT_JIS = 932, MAX_THREAD_COUNT }; // jichi 375/2014: Add offset of pusha/pushad // http://faydoc.tripod.com/cpu/pushad.htm