Reference counting for resource management

Bartosz Milewski bartosz-nospam at relisoft.com
Sun Nov 29 16:19:33 PST 2009


I don't think you need opAssign. The compiler will automatically use bitblit and postblit. 

Here's my implementation of a reference counted thread id structure for comparison:

struct Tid
{
    this(HANDLE h) 
    {
        _h = h;
        Counter * cnt = cast(Counter *) core.stdc.stdlib.malloc(Counter.sizeof);
        cnt._n = 1;
        _cnt = cast(shared Counter *) cnt;
    }
    ~this()
    {
        release();
    }
    this(this)
    {
        _cnt.inc;
    }
    // invalidates current Tid object
    Tid transfer()
    {
        Tid tid = { _h, _cnt };
        _cnt = null;
        return tid;
    }
    void release()
    {
        if (_cnt !is null)
        {
            uint newCount = _cnt.dec;
            if (newCount == 0)
            {
                CloseHandle(_h);
                core.stdc.stdlib.free(cast(Counter *)_cnt);
                _cnt = null;
            }
        }
    }
    void start()
    {
        assert(_h != INVALID_HANDLE_VALUE);
        if (ResumeThread(_h) == -1)
            throw new ThreadException("Error resuming thread");
    }
    void join(bool rethrow = true) 
    {
        if (_h != INVALID_HANDLE_VALUE)
            if (WaitForSingleObject(_h, INFINITE) != WAIT_OBJECT_0)
                throw new ThreadException("Join failed");
    }
    void setPriority() // dummy for now
    {
    }
private:
    // Revisit: implement using atomic add
    struct Counter
    {
        uint inc() shared { return ++_n; }
        uint dec() shared { return --_n; }

        uint _n = 1;
    }
private:
    HANDLE             _h = INVALID_HANDLE_VALUE;
    shared Counter * _cnt;
}

LMB Wrote:

> Hello,
> 
> I've been reading the forums for some time, but this is my first post here :-)
> 
> I am trying to create yet another D2 wrapper for SQLite. As usual with many C libraries, SQLite provides us some "objects" and functions to create and destroy them. So, I decided to encapsulate these SQLite objects in a struct, and use reference counting to destroys the objects as soon as I can safely do so.
> 
> The problem is that I can't make it work correctly in all situations. It guess that I am not increasing the reference count on every situation in which my object is copied, because I got "negative" reference counts in some tests. But this is just a guess, I am not sure at all.
> 
> So, is there any complete example on how to implement reference counting in D2?
> 
> I found some discussions about ref counting in D, like Bartoz's nice post (http://bartoszmilewski.wordpress.com/2009/08/19/the-anatomy-of-reference-counting/), but not a complete working example.
> 
> If there is no example around, I'd be pleased if someone could give me any advice. This is what one of my wrappers roughly looks like (for brevity, I removed all code not related to reference counting):
> 
> struct Database
> {
>    public this(in string fileName)
>    {
>       sqlite3_open(toStringz(fileName), &db_);
> 
>       refCount_ = cast(uint*)(malloc(uint.sizeof));
>       *refCount_ = 1;
>    }
> 
>    this(this)
>    body
>    {
>       ++(*refCount_);
>    }
> 
>    Database opAssign(Database other)
>    {
>       db_ = other.db_;
>       refCount_ = other.refCount_;
>       ++(*refCount_);
>       return this;
>    }
> 
>    public ~this()
>    {
>       if (refCount_ !is null)
>       {
>          --(*refCount_);
> 
>          if (*refCount_ == 0)
>          {
>             free(refCount_);
>             refCount_ = null;
>             immutable status = sqlite3_close(db_);
>          }
>       }
>    }
> 
>    private sqlite3* db_;
>    private uint* refCount_;
> }
> 
> 
> Thanks!
> 
> LMB
> 




More information about the Digitalmars-d mailing list