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