On Thursday, 24 July 2014 at 23:40:56 UTC, Jakob Ovrum wrote:
On Thursday, 24 July 2014 at 23:01:56 UTC, Robert burner
Schadek wrote:
I do this lazily in a function, because having it global froze
std.concurrency and std.process unittest. I couldn't figure
out why.
It could still be initialized lazily, using `emplace`, ala
---
private static __gshared Logger _defaultLogger;
Logger defaultLogger() @safe @nogc
{
static __gshared ubyte[__traits(classInstanceSize,
StdoutLogger)] buffer;
if(!_defaultLogger) // TODO: thread safety
_defaultLogger = () @trusted { return
emplace!StdoutLogger(buffer); }();
return _defaultLogger;
}
void defaultLogger(Logger newDefaultLogger) @safe @nogc
{
_defaultLogger = newDefaultLogger;
}
---
As said earlier, I think GC and Logger is a none issue. I mean
how often has anyone seen a Logger created in a loop over and
over again.
Some programs want to forego having a GC-heap entirely. That
means any GC allocation is a no-go.
Class instances don't have to be GC-allocated, so it's not an
issue to use classes.
nothrow will be hard as std.logger uses format, same for nogc
How often have you seen a formatted log message logged in a
loop? I'd wager that happens quite often. Using `format` is a
no-go as it completely thrashes the GC, it needs to use
`formattedWrite` to write directly to the underlying buffer
(such as a file).
Even using `formattedWrite` though, `nothrow` is still a
problem, and since exceptions are still GC-allocated, it
doesn't help with @nogc either. The latter is something we can
fix in the future though.
So you're thinking of a stack array?
No, MultiLogger could manage a non-GC yet still heap-allocated
array using std.container.array.Array. It uses the C heap
internally, i.e. malloc, realloc and free. Sortedness can be
used for searching by name in logarithmic time if desired.
Andrei asked for a simple array like multilogger. If it uses an
array sorting can be toggled by an template parameter
What about the log functions and there implementation as well
as the Logger specific LogLevel and name?
The log functions don't need to be virtual, only the
`writeLogMsg` function does, so these implementations can
either be final member functions of the interface, or UFCS
functions as I suggested in the corresponding line comment.
all log functions are templates.
The Logger-specific LogLevel and the name do not have to be
implemented by Logger. Leave it to concrete classes to
implement those. As an internal aid, an abstract GenericLogger
base class that manages these properties as member variables
(as Logger currently does) can help.
that seams manageable