From cfb4f831135c54b2f0711d9ef1a193f57918e9bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Thu, 20 Jul 2017 13:34:12 +0200 Subject: [PATCH] Add makeGCSafe/disposeGCSafe as GC safe variants of make/dispose. If necessary, these will call GC.addRange/GC.removeRange to avoid dangling GC references. --- source/vibe/internal/allocator.d | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/source/vibe/internal/allocator.d b/source/vibe/internal/allocator.d index 596b88f..d496aef 100644 --- a/source/vibe/internal/allocator.d +++ b/source/vibe/internal/allocator.d @@ -16,3 +16,26 @@ public import std.experimental.allocator.mallocator; s_threadAllocator = () @trusted { return allocatorObject(GCAllocator.instance); } (); return s_threadAllocator; } + +auto makeGCSafe(T, Allocator, A...)(Allocator allocator, A args) +{ + import core.memory : GC; + import std.traits : hasIndirections; + + auto ret = allocator.make!T(args); + static if (is (T == class)) enum tsize = __traits(classInstanceSize, T); + else enum tsize = T.sizeof; + static if (hasIndirections!T) + GC.addRange(cast(void*)ret, tsize, typeid(T)); + return ret; +} + +void disposeGCSafe(T, Allocator)(Allocator allocator, T obj) +{ + import core.memory : GC; + import std.traits : hasIndirections; + + static if (hasIndirections!T) + GC.removeRange(cast(void*)obj); + allocator.dispose(obj); +}