I'm having trouble getting MmFile
to work in a directory scanning algorithm.
When I'm stress-testing it as follows
foreach (dent; dirEntries(..)) {
const size_t K = ...;
const ulong size = ...;
scope auto mf = new MmFile(dent.name, MmFile.Mode.read, size, null, win)
}
I can't find a combination of size
and win
that works for all cases when reading data.
When I set
const size = 0;
const win = 64*1024;
the length gets calculated correctly.
But when dent.name
is an existing empty file it crashes in the destruction of the MMFile
throwing a
core.exception.FinalizeError...std.exception.ErrnoException@std.mmfile.d(490): munmap failed (Invalid argument).
And I can't recover this error by catching core.exception.FinalizeError
because its thrown in the destructor. I haven't tried
try { delete mm; } catch (core.exception.FinalizeError) { ; /* pass */}
Maybe that works.
Is this the default behavior when calling mmap
in C on existing empty files?
If so I think that MmFile should check for this error during construction.
The except gets thrown also when I replace scope
with an explicit delete
.
For now I simply skip calling MmFile
on empty files.
It sounds like a bug to me for MmFile
to barf on empty files regardless of what mmap
itself does. Please report it.
On a side note, I'd advise against using either scope
or delete
, as they're going to be removed from the language, because they're both unsafe. std.typecons.scoped replaces scope
in this context if you want to do that (though it's still unsafe). And as for delete
, destroy
will destroy the object without freeing its memory, and core.memory
can be used to free memory if you really want to, but in general, if you want to be worrying about freeing memory, then you should be manually managing your memory (with malloc
and free
and possibly emplace
) and not using the GC at all.