@@ -12,13 +12,68 @@ This license can be found at:
1212http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
1313*/
1414
15+ #include < string>
16+ #include < queue>
17+ #include < mutex>
1518#include < crtdbg.h>
1619#include " nvdaControllerInternal.h"
20+ #include " nvdaHelperRemote.h"
1721#include < common/log.h>
1822
23+ std::deque<std::tuple<int , std::wstring>> logQueue;
24+ std::mutex logQueueLock;
25+
26+ // Fetch all available messages from the queue
27+ // and send them onto NvDA via rpc.
28+ void log_flushQueue () {
29+ // Ensure this is never called from outside the manager thread.
30+ if (
31+ !inprocMgrThreadHandle
32+ || GetCurrentThreadId () != GetThreadId (inprocMgrThreadHandle)
33+ ) {
34+ QueueUserAPC (log_flushQueue_apcFunc, inprocMgrThreadHandle, 0 );
35+ return ;
36+ }
37+ std::deque<std::tuple<int , std::wstring>> tempQueue;
38+ {
39+ std::lock_guard lock{logQueueLock};
40+ tempQueue.swap (logQueue);
41+ }
42+ for (auto & [level, msg] : tempQueue) {
43+ nvdaControllerInternal_logMessage (level, GetCurrentProcessId (), msg.c_str ());
44+ }
45+
46+ }
47+
48+ void __stdcall log_flushQueue_apcFunc (ULONG_PTR data) {
49+ log_flushQueue ();
50+ }
51+
1952void logMessage (int level, const wchar_t * msg) {
20- if (level> LOGLEVEL_DEBUG ) nvdaControllerInternal_logMessage (level, GetCurrentProcessId (),msg);
53+ // Always log to any connected debugger
2154 OutputDebugString (msg);
55+ if (
56+ !inprocMgrThreadHandle
57+ || GetCurrentThreadId () != GetThreadId (inprocMgrThreadHandle)
58+ ) {
59+ // either the NVDA inproc manager thread is not yet running,
60+ // Or this message is being logged from outside NVDA's inproc manager thread.
61+ // So as to not block any app threads,
62+ // The message is queued for later fetching by NVDA's inproc manager thread
63+ {
64+ std::lock_guard lock{logQueueLock};
65+ logQueue.emplace_back (level, msg);
66+ }
67+ if (inprocMgrThreadHandle) {
68+ QueueUserAPC (log_flushQueue_apcFunc, inprocMgrThreadHandle, 0 );
69+ }
70+ } else {
71+ // The message is being logged from NVDA's inproc manager thread.
72+ // Log to NVDA via rpc directly.
73+ // But first flush any pending log messages from other threads to ensure they are kept in the right order
74+ log_flushQueue ();
75+ nvdaControllerInternal_logMessage (level,GetCurrentProcessId (),msg);
76+ }
2277}
2378
2479int NVDALogCrtReportHook (int reportType,const wchar_t *message,int *returnValue) {
@@ -38,4 +93,3 @@ int NVDALogCrtReportHook(int reportType,const wchar_t *message,int *returnValue)
3893 *returnValue=0 ;
3994 return true ;
4095}
41-
0 commit comments