1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
.. _managed-buffer:
**********************
Managed binary buffers
**********************
.. highlight:: c
::
#include <libcork/ds.h>
This section defines an interface for handling reference-counted binary
buffers. The :c:type:`cork_managed_buffer` type wraps a buffer with a
simple reference count, and takes care of freeing the necessary
resources when the reference count drops to zero. There should only be
a single :c:type:`cork_managed_buffer` instance for any given buffer,
regardless of how many threads or functions access that buffer. Each
thread or function that uses the buffer does so via a
:c:type:`cork_slice` instance. This type is meant to be allocated
directly on the stack (or in some other managed storage), and keeps a
pointer to the managed buffer instance that it slices. As its name
implies, a slice can refer to a subset of the buffer.
.. type:: struct cork_managed_buffer
A “managed buffer”, which wraps a buffer with a simple reference
count.
Managed buffer consumers should consider all of the fields of this
class private. Managed buffer implementors should fill in this
fields when constructing a new ``cork_managed_buffer`` instance.
.. member:: const void *buf
The buffer that this instance manages.
.. member:: size_t size
The size of :c:member:`buf`.
.. member:: volatile int ref_count
A reference count for the buffer. If this drops to ``0``, the
buffer will be finalized.
.. member:: struct cork_managed_buffer_iface *iface
The managed buffer implementation for this instance.
.. function:: struct cork_managed_buffer *cork_managed_buffer_ref(struct cork_managed_buffer *buf)
Atomically increase the reference count of a managed buffer. This
function is thread-safe.
.. function:: void cork_managed_buffer_unref(struct cork_managed_buffer *buf)
Atomically decrease the reference count of a managed buffer. If the
reference count falls to ``0``, the instance is freed. This function
is thread-safe.
.. function:: int cork_managed_buffer_slice(struct cork_slice *dest, struct cork_managed_buffer *buffer, size_t offset, size_t length)
int cork_managed_buffer_slice_offset(struct cork_slice *dest, struct cork_managed_buffer *buffer, size_t offset)
Initialize a new slice that refers to a subset of a managed buffer.
The *offset* and *length* parameters identify the subset. (For the
``_slice_offset`` variant, the *length* is calculated automatically
to include all of the managed buffer content starting from *offset*.)
If these parameters don't refer to a valid portion of the buffer, we
return ``false``, and you must not try to deference the slice's
:c:member:`buf <cork_slice.buf>` pointer. If the slice is valid, we
return ``true``.
Regardless of whether the new slice is valid, you **must** ensure
that you call :c:func:`cork_slice_finish()` when you are done with
the slice.
Predefined managed buffer implementations
-----------------------------------------
.. function:: struct cork_managed_buffer *cork_managed_buffer_new_copy(const void *buf, size_t size)
Make a copy of *buf*, and allocate a new managed buffer to manage
this copy. The copy will automatically be freed when the managed
buffer's reference count drops to ``0``.
.. type:: void (*cork_managed_buffer_freer)(void *buf, size_t size)
A finalization function for a managed buffer created by
:c:func:`cork_managed_buffer_new()`.
.. function:: struct cork_managed_buffer *cork_managed_buffer_new(const void *buf, size_t size, cork_managed_buffer_freer free)
Allocate a new managed buffer to manage an existing buffer (*buf*).
The existing buffer is *not* copied; the new managed buffer instance
takes control of it. When the managed buffer's reference count drops
to ``0``, it will call *free* to finalize *buf*.
This is a helper function, and keeps you from having to write a
complete custom managed buffer implementation when you don't need to
store any additional state in the managed buffer object.
.. note::
The *free* function is *not* responsible for freeing the
``cork_managed_buffer`` instance itself.
Custom managed buffer implementations
-------------------------------------
.. type:: struct cork_managed_buffer_iface
The interface of methods that managed buffer implementations must
provide.
.. member:: void (*free)(struct cork_managed_buffer *self)
Free the contents of a managed buffer, and the
``cork_managed_buffer`` instance itself.
|