Use dispose from std.experimental

This commit is contained in:
Eugen Wissner 2016-10-05 13:12:50 +02:00
parent 9241ec503c
commit 721bb110e5
11 changed files with 98 additions and 251 deletions

View File

@ -116,7 +116,7 @@ class ReadBuffer : Buffer
*/
~this()
{
finalize(allocator, _buffer);
dispose(allocator, _buffer);
}
///
@ -126,7 +126,7 @@ class ReadBuffer : Buffer
assert(b.capacity == 8192);
assert(b.length == 0);
finalize(defaultAllocator, b);
dispose(defaultAllocator, b);
}
/**
@ -169,7 +169,7 @@ class ReadBuffer : Buffer
b[];
assert(b.free == b.blockSize);
finalize(defaultAllocator, b);
dispose(defaultAllocator, b);
}
/**
@ -240,7 +240,7 @@ class ReadBuffer : Buffer
assert(result[10] == 20);
assert(result[14] == 24);
finalize(defaultAllocator, b);
dispose(defaultAllocator, b);
}
/**
@ -275,7 +275,7 @@ class ReadBuffer : Buffer
assert(result[9] == 9);
assert(b.length == 0);
finalize(defaultAllocator, b);
dispose(defaultAllocator, b);
}
}
@ -333,7 +333,7 @@ class WriteBuffer : Buffer
*/
~this()
{
finalize(allocator, _buffer);
dispose(allocator, _buffer);
}
/**
@ -385,7 +385,7 @@ class WriteBuffer : Buffer
b.written = b.length;
assert(b.length == 0);
finalize(defaultAllocator, b);
dispose(defaultAllocator, b);
}
/**
@ -485,7 +485,7 @@ class WriteBuffer : Buffer
assert(b._buffer[0] == 23 && b._buffer[1] == 255
&& b._buffer[2] == 48 && b._buffer[3] == 23 && b._buffer[4] == 255);
finalize(defaultAllocator, b);
dispose(defaultAllocator, b);
b = make!WriteBuffer(defaultAllocator, 2);
@ -495,7 +495,7 @@ class WriteBuffer : Buffer
assert(b.ring == 3);
assert(b.position == 3);
finalize(defaultAllocator, b);
dispose(defaultAllocator, b);
}
/**
@ -578,7 +578,7 @@ class WriteBuffer : Buffer
b.written = 4;
assert(b.length == 0);
finalize(defaultAllocator, b);
dispose(defaultAllocator, b);
}
/**
@ -631,6 +631,6 @@ class WriteBuffer : Buffer
assert(returnedBuf[0..b.length] == buf[0..6]);
b.written = b.length;
finalize(defaultAllocator, b);
dispose(defaultAllocator, b);
}
}

View File

@ -42,7 +42,7 @@ class SList(T)
{
static if (isFinalizable!T)
{
finalize(allocator, front);
dispose(allocator, front);
}
popFront();
}
@ -87,7 +87,7 @@ class SList(T)
l.front = values[1];
assert(l.front == values[1]);
finalize(defaultAllocator, l);
dispose(defaultAllocator, l);
}
/**
@ -118,7 +118,7 @@ class SList(T)
assert(l.front == value);
assert(!l.empty);
finalize(defaultAllocator, l);
dispose(defaultAllocator, l);
}
/**
@ -144,7 +144,7 @@ class SList(T)
auto n = first.next.next;
auto content = first.next.content;
finalize(allocator, first.next);
dispose(allocator, first.next);
first.next = n;
return content;
@ -162,7 +162,7 @@ class SList(T)
l.popFront();
assert(l.front == values[0]);
finalize(defaultAllocator, l);
dispose(defaultAllocator, l);
}
/**
@ -183,7 +183,7 @@ class SList(T)
auto temp = position.next.next;
auto content = position.next.content;
finalize(allocator, position.next);
dispose(allocator, position.next);
position.next = temp;
return content;
@ -203,7 +203,7 @@ class SList(T)
assert(l.remove() == 8);
assert(l.empty);
finalize(defaultAllocator, l);
dispose(defaultAllocator, l);
}
/**
@ -231,7 +231,7 @@ class SList(T)
l.reset();
assert(l.current == 5);
finalize(defaultAllocator, l);
dispose(defaultAllocator, l);
}
/**
@ -275,7 +275,7 @@ class SList(T)
assert(i != 2 || e == values[0]);
}
finalize(defaultAllocator, l);
dispose(defaultAllocator, l);
}
/// Ditto.
@ -315,7 +315,7 @@ class SList(T)
++i;
}
finalize(defaultAllocator, l);
dispose(defaultAllocator, l);
}
/**
@ -400,5 +400,5 @@ unittest
{
auto l = make!(SList!Stuff)(defaultAllocator);
finalize(defaultAllocator, l);
dispose(defaultAllocator, l);
}

View File

@ -41,7 +41,7 @@ class Queue(T)
{
static if (isFinalizable!T)
{
finalize(allocator, e);
dispose(allocator, e);
}
}
}
@ -99,7 +99,7 @@ class Queue(T)
q.insertBack(values[1]);
assert(q.front is values[0]);
finalize(defaultAllocator, q);
dispose(defaultAllocator, q);
}
/**
@ -129,7 +129,7 @@ class Queue(T)
assert(q.front == value);
assert(!q.empty);
finalize(defaultAllocator, q);
dispose(defaultAllocator, q);
}
/**
@ -150,7 +150,7 @@ class Queue(T)
q.insertBack(value);
assert(!q.empty);
finalize(defaultAllocator, q);
dispose(defaultAllocator, q);
}
/**
@ -167,7 +167,7 @@ class Queue(T)
{
auto n = first.next.next;
finalize(allocator, first.next);
dispose(allocator, first.next);
first.next = n;
return this;
@ -185,7 +185,7 @@ class Queue(T)
q.popFront();
assert(q.front is values[1]);
finalize(defaultAllocator, q);
dispose(defaultAllocator, q);
}
/**
@ -214,5 +214,5 @@ unittest
{
auto q = make!(Queue!int)(defaultAllocator);
finalize(defaultAllocator, q);
dispose(defaultAllocator, q);
}

View File

@ -22,7 +22,7 @@ import tanya.memory;
*
* v[1000] = value;
*
* finalize(defaultAllocator, v);
* dispose(defaultAllocator, v);
* ---
* it will allocate not only for one, but for 1000 elements. So this
* implementation is more suitable for sequential data with random access.
@ -57,7 +57,7 @@ class Vector(T)
*/
~this()
{
finalize(allocator, vector);
dispose(allocator, vector);
}
/**
@ -94,7 +94,7 @@ class Vector(T)
v.length = 0;
assert(v.length == 0);
finalize(defaultAllocator, v);
dispose(defaultAllocator, v);
}
/**
@ -116,7 +116,7 @@ class Vector(T)
void remove(size_t pos)
{
auto el = vector[pos];
finalize(allocator, el);
dispose(allocator, el);
}
}
@ -151,7 +151,7 @@ class Vector(T)
v[4] = values[1];
assert(v.length == 5);
finalize(defaultAllocator, v);
dispose(defaultAllocator, v);
}
/**
@ -182,7 +182,7 @@ class Vector(T)
v[0] = values[1];
assert(v[0] is values[1]);
finalize(defaultAllocator, v);
dispose(defaultAllocator, v);
}
/**
@ -250,7 +250,7 @@ class Vector(T)
assert(j != 2 || e is values[2]);
}
finalize(defaultAllocator, v);
dispose(defaultAllocator, v);
}
/**
@ -289,7 +289,7 @@ class Vector(T)
v.front = values[1];
assert(v.front == 15);
finalize(defaultAllocator, v);
dispose(defaultAllocator, v);
}
/**
@ -325,7 +325,7 @@ class Vector(T)
v.popFront();
assert(v.empty);
finalize(defaultAllocator, v);
dispose(defaultAllocator, v);
}
/**
@ -364,7 +364,7 @@ class Vector(T)
v.back = values[1];
assert(v.back == 15);
finalize(defaultAllocator, v);
dispose(defaultAllocator, v);
}
/**
@ -399,7 +399,7 @@ class Vector(T)
v.popBack();
assert(v.empty);
finalize(defaultAllocator, v);
dispose(defaultAllocator, v);
}
/// Container.
@ -413,5 +413,5 @@ unittest
{
auto v = make!(Vector!int)(defaultAllocator);
finalize(defaultAllocator, v);
dispose(defaultAllocator, v);
}

View File

@ -94,7 +94,7 @@ unittest
assert(input.length == 64);
assert(input[63] == 0);
defaultAllocator.finalize(input);
defaultAllocator.dispose(input);
}
{ // PKCS#7
auto input = defaultAllocator.makeArray!ubyte(50);
@ -139,7 +139,7 @@ unittest
}
}
defaultAllocator.finalize(input);
defaultAllocator.dispose(input);
}
{ // ANSI X.923
auto input = defaultAllocator.makeArray!ubyte(50);
@ -184,7 +184,7 @@ unittest
}
}
defaultAllocator.finalize(input);
defaultAllocator.dispose(input);
}
}
@ -240,8 +240,8 @@ unittest
removePadding(input, Mode.zero, 64);
assert(input == inputDup);
defaultAllocator.finalize(input);
defaultAllocator.finalize(inputDup);
defaultAllocator.dispose(input);
defaultAllocator.dispose(inputDup);
}
{ // PKCS#7
@ -257,8 +257,8 @@ unittest
removePadding(input, Mode.pkcs7, 64);
assert(input == inputDup);
defaultAllocator.finalize(input);
defaultAllocator.finalize(inputDup);
defaultAllocator.dispose(input);
defaultAllocator.dispose(inputDup);
}
{ // ANSI X.923
auto input = defaultAllocator.makeArray!ubyte(50);
@ -273,7 +273,7 @@ unittest
removePadding(input, Mode.pkcs7, 64);
assert(input == inputDup);
defaultAllocator.finalize(input);
defaultAllocator.finalize(inputDup);
defaultAllocator.dispose(input);
defaultAllocator.dispose(inputDup);
}
}

View File

@ -59,7 +59,7 @@ class EpollLoop : Loop
*/
~this()
{
finalize(defaultAllocator, epollEvents);
dispose(defaultAllocator, epollEvents);
}
/**
@ -125,7 +125,7 @@ class EpollLoop : Loop
// If it is a ConnectionWatcher
if (connection is null && connections[client] !is null)
{
finalize(defaultAllocator, connections[client]);
dispose(defaultAllocator, connections[client]);
connections[client] = null;
}
}
@ -198,7 +198,7 @@ class EpollLoop : Loop
catch (TransportException e)
{
swapPendings.insertBack(connection);
finalize(defaultAllocator, e);
dispose(defaultAllocator, e);
}
}
else if (ev.events & (EPOLLOUT | EPOLLERR | EPOLLHUP))

View File

@ -61,9 +61,9 @@ class SocketTransport : DuplexTransport
~this()
{
close(socket);
finalize(defaultAllocator, input_);
finalize(defaultAllocator, output_);
finalize(defaultAllocator, protocol_);
dispose(defaultAllocator, input_);
dispose(defaultAllocator, output_);
dispose(defaultAllocator, protocol_);
}
/**

View File

@ -70,9 +70,9 @@ abstract class Loop
*/
~this()
{
finalize(defaultAllocator, connections);
finalize(defaultAllocator, pendings);
finalize(defaultAllocator, swapPendings);
dispose(defaultAllocator, connections);
dispose(defaultAllocator, pendings);
dispose(defaultAllocator, swapPendings);
}
/**

View File

@ -128,7 +128,7 @@ class IOWatcher : ConnectionWatcher
~this()
{
finalize(defaultAllocator, transport_);
dispose(defaultAllocator, transport_);
}
/**
@ -185,7 +185,7 @@ class IOWatcher : ConnectionWatcher
else if (transport.disconnected)
{
transport.protocol.disconnected();
finalize(defaultAllocator, transport_);
dispose(defaultAllocator, transport_);
protocolFactory = null;
}
else if (transport.output.length)
@ -200,7 +200,7 @@ class IOWatcher : ConnectionWatcher
}
catch (TransportException e)
{
finalize(defaultAllocator, e);
dispose(defaultAllocator, e);
}
}
}

View File

@ -7,12 +7,17 @@
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
*/
*/
module tanya.memory.allocator;
import std.experimental.allocator;
import std.traits;
version (unittest)
{
import tanya.memory : defaultAllocator;
}
/**
* Allocator interface.
*/
@ -80,5 +85,23 @@ bool resizeArray(T)(shared Allocator allocator,
return true;
}
///
unittest
{
int[] p;
defaultAllocator.resizeArray(p, 20);
assert(p.length == 20);
defaultAllocator.resizeArray(p, 30);
assert(p.length == 30);
defaultAllocator.resizeArray(p, 10);
assert(p.length == 10);
defaultAllocator.resizeArray(p, 0);
assert(p is null);
}
enum bool isFinalizable(T) = is(T == class) || is(T == interface)
|| hasElaborateDestructor!T || isDynamicArray!T;

View File

@ -7,199 +7,23 @@
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
*/
*/
module tanya.memory;
public import tanya.memory.allocator;
public import std.experimental.allocator : make, makeArray, expandArray, shrinkArray, IAllocator;
import core.atomic;
import core.stdc.stdlib;
import std.traits;
version (Windows)
public
{
import core.sys.windows.windows;
}
else version (Posix)
{
public import tanya.memory.mmappool;
import core.sys.posix.pthread;
import tanya.memory.allocator;
import std.experimental.allocator : make, dispose, shrinkArray, expandArray, makeArray, dispose;
}
version (Windows)
shared Allocator allocator;
@property ref shared(Allocator) defaultAllocator()
{
package alias Mutex = CRITICAL_SECTION;
package alias destroyMutex = DeleteCriticalSection;
}
else version (Posix)
{
package alias Mutex = pthread_mutex_t;
package void destroyMutex(pthread_mutex_t* mtx)
import tanya.memory.mallocator;
if (allocator is null)
{
pthread_mutex_destroy(mtx) && assert(0);
}
allocator = Mallocator.instance;
}
return allocator;
}
@property void defaultAllocator(shared Allocator allocator) @safe nothrow
{
_defaultAllocator = allocator;
}
@property shared(Allocator) defaultAllocator() @safe nothrow
{
return _defaultAllocator;
}
static this() @safe nothrow
{
defaultAllocator = MmapPool.instance;
}
package struct Monitor
{
Object.Monitor impl; // for user-level monitors
void delegate(Object) @nogc[] devt; // for internal monitors
size_t refs; // reference count
version (Posix)
{
Mutex mtx;
}
}
package @property ref shared(Monitor*) monitor(Object h) pure nothrow
{
return *cast(shared Monitor**)&h.__monitor;
}
/**
* Destroys and then deallocates (using $(D_PARAM allocator)) the class
* object referred to by a $(D_KEYWORD class) or $(D_KEYWORD interface)
* reference. It is assumed the respective entities had been allocated with
* the same allocator.
*
* Params:
* A = The type of the allocator used for the ojbect allocation.
* T = The type of the object that should be destroyed.
* allocator = The allocator used for the object allocation.
* p = The object should be destroyed.
*/
void finalize(A, T)(auto ref A allocator, ref T p)
if (is(T == class) || is(T == interface))
{
static if (is(T == interface))
{
auto ob = cast(Object) p;
}
else
{
alias ob = p;
}
auto pp = cast(void*) ob;
auto ppv = cast(void**) pp;
if (!pp || !*ppv)
{
return;
}
auto support = (cast(void*) ob)[0 .. typeid(ob).initializer.length];
auto pc = cast(ClassInfo*) *ppv;
auto c = *pc;
do
{
if (c.destructor)
{
(cast(void function(Object)) c.destructor)(ob);
}
} while ((c = c.base) !is null);
// Take care of monitors for synchronized blocks
if (ppv[1])
{
shared(Monitor)* m = atomicLoad!(MemoryOrder.acq)(ob.monitor);
if (m !is null)
{
auto mc = cast(Monitor*) m;
if (!atomicOp!("-=")(m.refs, cast(size_t) 1))
{
foreach (v; mc.devt)
{
if (v)
{
v(ob);
}
}
if (mc.devt.ptr)
{
free(mc.devt.ptr);
}
destroyMutex(&mc.mtx);
free(mc);
atomicStore!(MemoryOrder.rel)(ob.monitor, null);
}
}
}
*ppv = null;
allocator.deallocate(support);
p = null;
}
/// Ditto.
void finalize(A, T)(auto ref A allocator, ref T *p)
if (is(T == struct))
{
if (p is null)
{
return;
}
static if (hasElaborateDestructor!T)
{
*p.__xdtor();
}
allocator.deallocate((cast(void*)p)[0 .. T.sizeof]);
p = null;
}
/// Ditto.
void finalize(A, T)(auto ref A allocator, ref T[] p)
{
static if (hasElaborateDestructor!T)
{
foreach (ref e; p)
{
finalize(allocator, e);
}
}
allocator.deallocate(p);
p = null;
}
bool resizeArray(T, A)(auto ref A allocator, ref T[] array, in size_t length)
@trusted
{
if (length == array.length)
{
return true;
}
if (array is null && length > 0)
{
array = makeArray!T(allocator, length);
return array !is null;
}
if (length == 0)
{
finalize(allocator, array);
return true;
}
void[] buf = array;
if (!allocator.reallocate(buf, length * T.sizeof))
{
return false;
}
array = cast(T[]) buf;
return true;
}
enum bool isFinalizable(T) = is(T == class) || is(T == interface)
|| hasElaborateDestructor!T || isDynamicArray!T;
private shared Allocator _defaultAllocator;