www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Reference counting for resource management

reply LMB <lmbarros gmail.com> writes:
Hello,

This should be my first post here, but I just posted the same message on the
"standard" D newsgroup by mistake (what a noob! :-P) So, here I go again, on
the right forum this time...

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-r
ference-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
Nov 27 2009
parent reply Don <nospam nospam.com> writes:
LMB wrote:
 Hello,
 
 This should be my first post here, but I just posted the same message on the
"standard" D newsgroup by mistake (what a noob! :-P) So, here I go again, on
the right forum this time...
 
 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 don't think so. While trying to do it, Bartosz found some severe bugs in D which made it impossible; they were fixed in the last release. He's since found bug 3516 might still prevent a complete implementation.
 
 I found some discussions about ref counting in D, like Bartoz's nice post
(http://bartoszmilewski.wordpress.com/2009/08/19/the-anatomy-of-r
ference-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
 
Nov 28 2009
parent LMB <nomail nowhere.com> writes:
Don Wrote:

 LMB wrote:
 [...]
 So, is there any complete example on how to implement reference counting in D2?
I don't think so. While trying to do it, Bartosz found some severe bugs in D which made it impossible; they were fixed in the last release. He's since found bug 3516 might still prevent a complete implementation.
Great! This bug 3516 ("Destructor not called on temporaries") was, er, bugging me too. Good to know that my lack of knowledge of D is not the only reason I could not make my code work. :-) Thanks for the answer!
Nov 29 2009