AuroraRuntime/Source/Logging/Sinks/IPCSink.cpp
Reece Wilson 7fb73ccdb4 [+] IPC Logger: Added optional stream frame header (single u32) option
[*] FIX: Missing `this->isStream = isStream;`
[*] FIX: Blocking APIs under async objects under NT were using illegal calls that were for some reason not failing
2022-07-05 20:48:33 +01:00

109 lines
2.5 KiB
C++

/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: IPCSink.cpp
Date: 2022-6-16
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "IPCSink.hpp"
namespace Aurora::Logging::Sinks
{
IPCSink::IPCSink(const AuSPtr<Aurora::IO::IPC::IPCPipe> &pipe, bool lengthPrefixed) : pipe_(pipe), lengthPrefixed_(lengthPrefixed)
{
}
bool IPCSink::Init()
{
this->logMutex_ = AuThreadPrimitives::MutexUnique();
return static_cast<bool>(this->pipe_) && static_cast<bool>(this->logMutex_);
}
AuSPtr<IO::IPC::IPCPipe> IPCSink::ToPipe()
{
return this->pipe_;
}
void IPCSink::OnMessageBlocking(AuUInt8 level, const ConsoleMessage &msg)
{
AU_LOCK_GUARD(this->logMutex_);
auto str = msg.ToPersistentString();
auto startOffset = this->logBuffer_.GetWriteOffset();
if (this->lengthPrefixed_)
{
if (this->logBuffer_.base == this->logBuffer_.writePtr)
{
this->logBuffer_.Write<AuUInt32>(0);
}
}
msg.Write(this->logBuffer_);
if (!this->logBuffer_)
{
this->logBuffer_.writePtr = this->logBuffer_.base + startOffset;
}
}
bool IPCSink::OnMessageNonblocking(AuUInt8 level, const ConsoleMessage &msg)
{
return true;
}
void IPCSink::OnFlush()
{
if (!this->logMutex_)
{
return;
}
AU_LOCK_GUARD(this->logMutex_);
if (!this->logBuffer_.RemainingBytes())
{
return;
}
auto len = this->logBuffer_.writePtr - this->logBuffer_.base;
if (this->lengthPrefixed_)
{
this->logBuffer_.writePtr = this->logBuffer_.base;
this->logBuffer_.Write<AuUInt32>(len);
}
this->pipe_->Write(AuMemoryViewStreamRead(this->logBuffer_.base, this->logBuffer_.base + len));
this->logBuffer_.ResetPositions();
}
IIPCLogger *NewIPCSinkNew(const AuString &str, bool lengthPrefixed)
{
auto pipe = AuIPC::ImportPipe(str);
if (!pipe)
{
return nullptr;
}
auto logger = _new IPCSink(pipe, lengthPrefixed);
if (!logger)
{
return nullptr;
}
if (!logger->Init())
{
return nullptr;
}
return logger;
}
void NewIPCSinkRelease(IIPCLogger *logger)
{
AuSafeDelete<IPCSink *>(logger);
}
}