File: managed-buffer.rst

package info (click to toggle)
libcork 1.0.0~rc3-4
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 2,024 kB
  • sloc: ansic: 12,975; python: 605; makefile: 331; sh: 238
file content (125 lines) | stat: -rw-r--r-- 4,615 bytes parent folder | download | duplicates (4)
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.