Top |
Atomically reference counted dataAtomically reference counted data — Allocated memory with atomic reference counting semantics |
gpointer | g_atomic_rc_box_alloc () |
gpointer | g_atomic_rc_box_alloc0 () |
#define | g_atomic_rc_box_new() |
#define | g_atomic_rc_box_new0() |
gpointer | g_atomic_rc_box_dup () |
gpointer | g_atomic_rc_box_acquire () |
void | g_atomic_rc_box_release () |
void | g_atomic_rc_box_release_full () |
gsize | g_atomic_rc_box_get_size () |
An "atomically reference counted box", or "ArcBox", is an opaque wrapper data type that is guaranteed to be as big as the size of a given data type, and which augments the given data type with thread safe reference counting semantics for its memory management.
ArcBox is useful if you have a plain old data type, like a structure typically placed on the stack, and you wish to provide additional API to use it on the heap; or if you want to implement a new type to be passed around by reference without necessarily implementing copy/free semantics or your own reference counting.
The typical use is:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
typedef struct { char *name; char *address; char *city; char *state; int age; } Person; Person * person_new (void) { return g_atomic_rc_box_new0 (Person); } |
Every time you wish to acquire a reference on the memory, you should
call g_atomic_rc_box_acquire()
; similarly, when you wish to release a reference
you should call g_atomic_rc_box_release()
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// Add a Person to the Database; the Database acquires ownership // of the Person instance void add_person_to_database (Database *db, Person *p) { db->persons = g_list_prepend (db->persons, g_atomic_rc_box_acquire (p)); } // Removes a Person from the Database; the reference acquired by // add_person_to_database() is released here void remove_person_from_database (Database *db, Person *p) { db->persons = g_list_remove (db->persons, p); g_atomic_rc_box_release (p); } |
If you have additional memory allocated inside the structure, you can
use g_atomic_rc_box_release_full()
, which takes a function pointer, which
will be called if the reference released was the last:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
void person_clear (Person *p) { g_free (p->name); g_free (p->address); g_free (p->city); g_free (p->state); } void remove_person_from_database (Database *db, Person *p) { db->persons = g_list_remove (db->persons, p); g_atomic_rc_box_release_full (p, (GDestroyNotify) person_clear); } |
If you wish to transfer the ownership of a reference counted data
type without increasing the reference count, you can use g_steal_pointer()
:
1 2 3 4 5 |
Person *p = g_atomic_rc_box_new (Person); fill_person_details (p); add_person_to_database (db, g_steal_pointer (&p)); |
The reference counting operations on data allocated using g_atomic_rc_box_alloc()
,
g_atomic_rc_box_new()
, and g_atomic_rc_box_dup()
are guaranteed to be atomic, and thus
can be safely be performed by different threads. It is important to note that
only the reference acquisition and release are atomic; changes to the content
of the data are your responsibility.
If you want to add g_autoptr()
support to your plain old data type through
reference counting, you can use the G_DEFINE_AUTOPTR_CLEANUP_FUNC()
and
g_atomic_rc_box_release()
:
1 |
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MyDataStruct, g_atomic_rc_box_release) |
If you need to clear the contents of the data, you will need to use an
ancillary function that calls g_rc_box_release_full()
:
1 2 3 4 5 6 7 8 |
static void my_data_struct_release (MyDataStruct *data) { // my_data_struct_clear() is defined elsewhere g_atomic_rc_box_release_full (data, (GDestroyNotify) my_data_struct_clear); } G_DEFINE_AUTOPTR_CLEANUP_FUNC (MyDataStruct, my_data_struct_release) |
gpointer
g_atomic_rc_box_alloc (gsize block_size
);
Allocates block_size
bytes of memory, and adds atomic
reference counting semantics to it.
The data will be freed when its reference count drops to zero.
The allocated data is guaranteed to be suitably aligned for any built-in type.
Since: 2.58
gpointer
g_atomic_rc_box_alloc0 (gsize block_size
);
Allocates block_size
bytes of memory, and adds atomic
reference counting semantics to it.
The contents of the returned data is set to zero.
The data will be freed when its reference count drops to zero.
The allocated data is guaranteed to be suitably aligned for any built-in type.
Since: 2.58
#define g_atomic_rc_box_new(type)
A convenience macro to allocate atomically reference counted
data with the size of the given type
.
This macro calls g_atomic_rc_box_alloc()
with sizeof (@type)
and
casts the returned pointer to a pointer of the given type
,
avoiding a type cast in the source code.
a pointer to the allocated
memory, cast to a pointer for the given type
.
[transfer full][not nullable]
Since: 2.58
#define g_atomic_rc_box_new0(type)
A convenience macro to allocate atomically reference counted
data with the size of the given type
, and set its contents
to zero.
This macro calls g_atomic_rc_box_alloc0()
with sizeof (@type)
and
casts the returned pointer to a pointer of the given type
,
avoiding a type cast in the source code.
a pointer to the allocated
memory, cast to a pointer for the given type
.
[transfer full][not nullable]
Since: 2.58
gpointer g_atomic_rc_box_dup (gsize block_size
,gconstpointer mem_block
);
Allocates a new block of data with atomic reference counting
semantics, and copies block_size
bytes of mem_block
into it.
block_size |
the number of bytes to copy, must be greater than 0 |
|
mem_block |
the memory to copy. |
[not nullable] |
Since: 2.58
gpointer
g_atomic_rc_box_acquire (gpointer mem_block
);
Atomically acquires a reference on the data pointed by mem_block
.
Since: 2.58
void
g_atomic_rc_box_release (gpointer mem_block
);
Atomically releases a reference on the data pointed by mem_block
.
If the reference was the last one, it will free the
resources allocated for mem_block
.
Since: 2.58
void g_atomic_rc_box_release_full (gpointer mem_block
,GDestroyNotify clear_func
);
Atomically releases a reference on the data pointed by mem_block
.
If the reference was the last one, it will call clear_func
to clear the contents of mem_block
, and then will free the
resources allocated for mem_block
.
mem_block |
a pointer to reference counted data. |
[transfer full][not nullable] |
clear_func |
a function to call when clearing the data. |
[not nullable] |
Since: 2.58