On Mon, 30 Nov 2009 03:19:33 +0300, Bartosz Milewski
<bartosz-nos...@relisoft.com> wrote:
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
I think RefCounted should be flexible enough to re-usable for other data
structures, too (e.g. so that it could be part of Phobos).
By the way, your code has a bug:
Tid tid; // or release() and exisiting Tid
Tid tid2 = tid; // segfault since you don't check if _cnt is null in
postblit