Lines NewlineFilter::FlushLinesFromTerminatedProcess(DWORD pid, HANDLE handle) { Lines lines; if (m_lineBuffers.find(pid) != m_lineBuffers.end()) { if (!m_lineBuffers[pid].empty()) { // timestamp not filled, this will be done by the loopback source lines.push_back(Line(0, FILETIME(), pid, "<flush>", m_lineBuffers[pid], nullptr)); } m_lineBuffers.erase(pid); } auto processName = Str(ProcessInfo::GetProcessName(handle)).str(); auto info = ProcessInfo::GetProcessInfo(handle); std::string infoStr = stringbuilder() << "<process started at " << info << " has now terminated>"; lines.push_back(Line(0, FILETIME(), pid, processName, infoStr, nullptr)); return lines; }
noinline void Trace(const mpt::log::Context & context) { // This will get called in realtime contexts and hot paths. // No blocking allowed here. const uint32 index = NextIndex.fetch_add(1); #if 1 LARGE_INTEGER time; time.QuadPart = 0; QueryPerformanceCounter(&time); const uint64 timestamp = time.QuadPart; #else FILETIME time = FILETIME(); GetSystemTimeAsFileTime(&time); const uint64 timestamp = (static_cast<uint64>(time.dwHighDateTime) << 32) | (static_cast<uint64>(time.dwLowDateTime) << 0); #endif const uint32 threadid = static_cast<uint32>(GetCurrentThreadId()); mpt::log::Trace::Entry & entry = Entries[index % Entries.size()]; entry.Index = index; entry.ThreadId = threadid; entry.Timestamp = timestamp; entry.Function = context.function; entry.File = context.file; entry.Line = context.line; }