The refcounting logic is unsafe as written; correct refcounting in the multithreaded case can be subtle and not something I would recommend attempting on your own.
(Is there a reason to use a boxed type rather than deriving from gobject, which has correct refcounting?)
The two biggest thread-related issues are with _unref; first, there is a race between the read of the refcount and acting on it, and secondly g_atomic_int_compare_and_exchange is misused here, since it can potentially fail and is supposed to be used in a retrying loop.
The requirements for refcounting here are at least a little simpler than gobject's (since I don't think you have to worry about e.g. revivification or weak/floating refs); if you were to continue with a boxed type, a correct implementation for your simple case would look something like this:
The refcounting logic is unsafe as written; correct refcounting in the multithreaded case can be subtle and not something I would recommend attempting on your own.
(Is there a reason to use a boxed type rather than deriving from gobject, which has correct refcounting?)
The two biggest thread-related issues are with _unref; first, there is a race between the read of the refcount and acting on it, and secondly g_atomic_ int_compare_ and_exchange is misused here, since it can potentially fail and is supposed to be used in a retrying loop.
The requirements for refcounting here are at least a little simpler than gobject's (since I don't think you have to worry about e.g. revivification or weak/floating refs); if you were to continue with a boxed type, a correct implementation for your simple case would look something like this:
CouchDBDatabas eInfo * database_ info_ref (CouchDBDatabas eInfo *dbinfo) val_if_ fail (dbinfo != NULL, NULL); val_if_ fail (dbinfo->ref_count > 0, NULL);
couchdb_
{
g_return_
g_return_
g_atomic_ int_inc( &dbinfo- >ref_count) ;
return dbinfo;
}
void database_ info_unref (CouchDBDatabas eInfo *dbinfo)
couchdb_
{
gboolean is_zero;
g_return_if_fail (dbinfo != NULL);
g_return_if_fail (dbinfo->ref_count > 0);
is_zero = g_atomic_ int_dec_ and_test( &dbinfo- >ref_count) ;
if (is_zero) { eInfo, dbinfo);
g_free (dbinfo->dbname);
g_slice_free (CouchDBDatabas
}
}
(Also, is single-space-indent acceptable from a CodingStyle point of view?)