Use of mutex in destructors

Simen Kjaeraas simen.kjaras at gmail.com
Fri Apr 27 09:40:49 PDT 2012


On Fri, 27 Apr 2012 17:55:02 +0200, Rene Zwanenburg  
<renezwanenburg at gmail.com> wrote:

> I _could_ modify the system to use ref counting everywhere, but I'm
> reluctant to do that.

You wouldn't really need to. Only the texture struct would need that.
Look to std.typecons's RefCounted[1] for inspiration. One could easily
imagine and RAII version of that, which would take as a template parameter
a function that would run in the destructor. Simple implementation (I'm
lazy):

import std.typecons : Tuple;
import std.traits : hasIndirections;
import std.algorithm : swap, move;
import core.stdc.stdlib : malloc, free;
import std.conv : emplace;

struct RefCountedDestructor(T, alias destructor = {}) if (!is(T == class))  
{
     Tuple!(T, "_payload", size_t, "_count")* _store;

     this(A...)(A args) {
         auto sz = (*_store).sizeof;
         auto p = malloc(sz)[0..sz];
         static if (hasIndirections!T)
         {
             GC.addRange(p.ptr, sz);
         }
         emplace(cast(T*)p.ptr, args);
         _store = cast(typeof(_store))p.ptr;
         _store._count = 1;
     }

     this(this) {
         _store._count++;
     }

     ~this() {
         assert(_store._count > 0);
         if (--_store._count) {
             return;
         }

         destructor();

         clear(_store._payload);
         static if (hasIndirections!T) {
             GC.removeRange(_store);
         }
         _store = null;
     }

     void opAssign(typeof(this) rhs)
     {
         swap(_store, rhs._store);
     }

     void opAssign(T rhs)
     {
         _store._payload = move(rhs);
     }

     @property
     ref T payload( ) {
         return _store._payload;
     }

     @property const
     ref const(T) payload( ) {
         return _store._payload;
     }

     alias payload this;
}

Usage:

void main() {
     auto a = RefCountedDestructor!(int, {writeln("Goodbye, cruel  
world")})(4);
}


More information about the Digitalmars-d-learn mailing list