## Atomically reference counted data Atomically reference counted data — Allocated memory with atomic reference counting semantics |

## Functions

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 ()

## Includes

    #include <glib.h>
    #include <glib/gi18n.h>

## Description

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));

#### Thread safety

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.

#### Automatic pointer clean up

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)

## Functions

### g_atomic_rc_box_alloc ()

    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.

#### Parameters

block_size | the size of the allocation, must be greater than 0 |

#### Returns

a pointer to the allocated memory.

[transfer full][not nullable]

Since: 2.58

### g_atomic_rc_box_alloc0 ()

    gpointer
    g_atomic_rc_box_alloc0 (gsize block_size);

Allocates `block_size` bytes of memory, and adds atomic referenc 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.

#### Parameters

block_size | the size of the allocation, must be greater than 0 |

#### Returns

a pointer to the allocated memory.

[transfer full][not nullable]

Since: 2.58

### g_atomic_rc_box_new()

    #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.

#### Parameters

type | the type to allocate, typically a structure name |

#### Returns

a pointer to the allocated memory, cast to a pointer for the given `type` .

[transfer full][not nullable]

Since: 2.58

### g_atomic_rc_box_new0()

    #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.

#### Parameters

type | the type to allocate, typically a structure name |

#### Returns

a pointer to the allocated memory, cast to a pointer for the given `type` .

[transfer full][not nullable]

Since: 2.58

### g_atomic_rc_box_dup ()

    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.

#### Parameters

block_size | the number of bytes to copy, must be greater than 0 |
mem_block | the memory to copy. | [not nullable]

#### Returns

a pointer to the allocated memory.

[transfer full][not nullable]

Since: 2.58

### g_atomic_rc_box_acquire ()

    gpointer
    g_atomic_rc_box_acquire (gpointer mem_block);

Atomically acquires a reference on the data pointed by `mem_block` .

#### Parameters

mem_block | a pointer to reference counted data. | [not nullable]

#### Returns

a pointer to the data, with its reference count increased.

[transfer full][not nullable]

Since: 2.58

### g_atomic_rc_box_release ()

    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` .

#### Parameters

mem_block | a pointer to reference counted data. | [transfer full][not nullable]

Since: 2.58

### g_atomic_rc_box_release_full ()

    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` .

#### Parameters

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

### g_atomic_rc_box_get_size ()

    gsize
    g_atomic_rc_box_get_size (gpointer mem_block);

Retrieves the size of the reference counted data pointed by `mem_block` .

#### Parameters

mem_block | a pointer to reference counted data. | [not nullable]

#### Returns

the size of the data, in bytes

Since: 2.58