commit 3b8db51
Michael Forney
·
2014-02-06 08:56:18 +0000 UTC
parent 3a416f3
Split exporters into destructors
M
buffer.c
+16,
-13
1@@ -37,17 +37,10 @@ void buffer_initialize(struct buffer * buffer,
2 buffer->references = 1;
3 buffer->map_references = 0;
4 buffer->exporters = NULL;
5+ buffer->destructors = NULL;
6 pixman_region32_init_rect(&buffer->base.damage, 0, 0, width, height);
7 }
8
9-EXPORT
10-void wld_exporter_initialize(struct wld_exporter * exporter,
11- const struct wld_exporter_impl * impl)
12-{
13- *((const struct wld_exporter_impl **) &exporter->impl) = impl;
14- exporter->next = NULL;
15-}
16-
17 EXPORT
18 bool wld_map(struct wld_buffer * base)
19 {
20@@ -84,7 +77,7 @@ bool wld_export(struct wld_buffer * base,
21
22 for (exporter = buffer->exporters; exporter; exporter = exporter->next)
23 {
24- if (exporter->impl->export(exporter, &buffer->base, type, object))
25+ if (exporter->export(exporter, &buffer->base, type, object))
26 return true;
27 }
28
29@@ -101,6 +94,16 @@ void wld_buffer_add_exporter(struct wld_buffer * base,
30 buffer->exporters = exporter;
31 }
32
33+EXPORT
34+void wld_buffer_add_destructor(struct wld_buffer * base,
35+ struct wld_destructor * destructor)
36+{
37+ struct buffer * buffer = (void *) base;
38+
39+ destructor->next = buffer->destructors;
40+ buffer->destructors = destructor;
41+}
42+
43 EXPORT
44 void wld_buffer_reference(struct wld_buffer * base)
45 {
46@@ -113,7 +116,7 @@ EXPORT
47 void wld_buffer_unreference(struct wld_buffer * base)
48 {
49 struct buffer * buffer = (void *) base;
50- struct wld_exporter * exporter, * next;
51+ struct wld_destructor * destructor, * next;
52
53 if (--buffer->references > 0)
54 return;
55@@ -123,10 +126,10 @@ void wld_buffer_unreference(struct wld_buffer * base)
56
57 pixman_region32_fini(&buffer->base.damage);
58
59- for (exporter = buffer->exporters, next = exporter ? exporter->next : NULL;
60- exporter; exporter = next, next = exporter ? exporter->next : NULL)
61+ for (destructor = buffer->destructors; destructor; destructor = next)
62 {
63- exporter->impl->destroy(exporter);
64+ next = destructor->next;
65+ destructor->destroy(destructor);
66 }
67
68 buffer->base.impl->destroy(buffer);
M
dumb.c
+34,
-41
1@@ -48,7 +48,6 @@ struct dumb_buffer
2
3 #include "interface/context.h"
4 #include "interface/buffer.h"
5-#include "interface/exporter.h"
6 #define DRM_DRIVER_NAME dumb
7 #include "interface/drm.h"
8 IMPL(dumb_context, wld_context)
9@@ -79,6 +78,39 @@ struct wld_renderer * context_create_renderer(struct wld_context * context)
10 return wld_create_renderer(wld_pixman_context);
11 }
12
13+static bool export(struct wld_exporter * exporter, struct wld_buffer * base,
14+ uint32_t type, union wld_object * object)
15+{
16+ struct dumb_buffer * buffer = dumb_buffer(base);
17+
18+ switch (type)
19+ {
20+ case WLD_DRM_OBJECT_HANDLE:
21+ object->u32 = buffer->handle;
22+ return true;
23+ case WLD_DRM_OBJECT_PRIME_FD:
24+ if (drmPrimeHandleToFD(buffer->context->fd, buffer->handle,
25+ DRM_CLOEXEC, &object->i) != 0)
26+ {
27+ return false;
28+ }
29+
30+ return true;
31+ case WLD_DRM_OBJECT_GEM_NAME:
32+ {
33+ struct drm_gem_flink flink = { .handle = buffer->handle };
34+
35+ if (drmIoctl(buffer->context->fd, DRM_IOCTL_GEM_FLINK, &flink) != 0)
36+ return false;
37+
38+ object->u32 = flink.name;
39+ return true;
40+ }
41+ default:
42+ return false;
43+ }
44+}
45+
46 static struct buffer * new_buffer(struct dumb_context * context,
47 uint32_t width, uint32_t height,
48 uint32_t format, uint32_t handle,
49@@ -93,7 +125,7 @@ static struct buffer * new_buffer(struct dumb_context * context,
50 width, height, format, pitch);
51 buffer->context = context;
52 buffer->handle = handle;
53- wld_exporter_initialize(&buffer->exporter, &wld_exporter_impl);
54+ buffer->exporter.export = &export;
55 wld_buffer_add_exporter(&buffer->base.base, &buffer->exporter);
56
57 return &buffer->base;
58@@ -221,42 +253,3 @@ void buffer_destroy(struct buffer * base)
59 free(buffer);
60 }
61
62-/**** Exporter ****/
63-
64-bool exporter_export(struct wld_exporter * exporter, struct wld_buffer * base,
65- uint32_t type, union wld_object * object)
66-{
67- struct dumb_buffer * buffer = dumb_buffer(base);
68-
69- switch (type)
70- {
71- case WLD_DRM_OBJECT_HANDLE:
72- object->u32 = buffer->handle;
73- return true;
74- case WLD_DRM_OBJECT_PRIME_FD:
75- if (drmPrimeHandleToFD(buffer->context->fd, buffer->handle,
76- DRM_CLOEXEC, &object->i) != 0)
77- {
78- return false;
79- }
80-
81- return true;
82- case WLD_DRM_OBJECT_GEM_NAME:
83- {
84- struct drm_gem_flink flink = { .handle = buffer->handle };
85-
86- if (drmIoctl(buffer->context->fd, DRM_IOCTL_GEM_FLINK, &flink) != 0)
87- return false;
88-
89- object->u32 = flink.name;
90- return true;
91- }
92- default:
93- return false;
94- }
95-}
96-
97-void exporter_destroy(struct wld_exporter * exporter)
98-{
99-}
100-
M
intel.c
+24,
-30
1@@ -54,7 +54,6 @@ struct intel_buffer
2 #include "interface/context.h"
3 #include "interface/renderer.h"
4 #include "interface/buffer.h"
5-#include "interface/exporter.h"
6 #define DRM_DRIVER_NAME intel
7 #include "interface/drm.h"
8 IMPL(intel_context, wld_context)
9@@ -112,6 +111,29 @@ struct wld_renderer * context_create_renderer(struct wld_context * base)
10 return NULL;
11 }
12
13+static bool export(struct wld_exporter * exporter, struct wld_buffer * base,
14+ uint32_t type, union wld_object * object)
15+{
16+ struct intel_buffer * buffer = intel_buffer(base);
17+
18+ switch (type)
19+ {
20+ case WLD_DRM_OBJECT_HANDLE:
21+ object->u32 = buffer->bo->handle;
22+ return true;
23+ case WLD_DRM_OBJECT_PRIME_FD:
24+ if (drm_intel_bo_gem_export_to_prime(buffer->bo, &object->i) != 0)
25+ return false;
26+ return true;
27+ case WLD_DRM_OBJECT_GEM_NAME:
28+ if (drm_intel_bo_flink(buffer->bo, &object->u32) != 0)
29+ return false;
30+ return true;
31+ default:
32+ return false;
33+ }
34+}
35+
36 static struct buffer * new_buffer(uint32_t width, uint32_t height,
37 uint32_t format, uint32_t pitch,
38 drm_intel_bo * bo)
39@@ -124,7 +146,7 @@ static struct buffer * new_buffer(uint32_t width, uint32_t height,
40 buffer_initialize(&buffer->base, &wld_buffer_impl,
41 width, height, format, pitch);
42 buffer->bo = bo;
43- wld_exporter_initialize(&buffer->exporter, &wld_exporter_impl);
44+ buffer->exporter.export = &export;
45 wld_buffer_add_exporter(&buffer->base.base, &buffer->exporter);
46
47 return &buffer->base;
48@@ -371,31 +393,3 @@ void buffer_destroy(struct buffer * base)
49 free(buffer);
50 }
51
52-/**** Exporter ****/
53-bool exporter_export(struct wld_exporter * exporter, struct wld_buffer * base,
54- uint32_t type, union wld_object * object)
55-{
56- struct intel_buffer * buffer = intel_buffer(base);
57-
58- switch (type)
59- {
60- case WLD_DRM_OBJECT_HANDLE:
61- object->u32 = buffer->bo->handle;
62- return true;
63- case WLD_DRM_OBJECT_PRIME_FD:
64- if (drm_intel_bo_gem_export_to_prime(buffer->bo, &object->i) != 0)
65- return false;
66- return true;
67- case WLD_DRM_OBJECT_GEM_NAME:
68- if (drm_intel_bo_flink(buffer->bo, &object->u32) != 0)
69- return false;
70- return true;
71- default:
72- return false;
73- }
74-}
75-
76-void exporter_destroy(struct wld_exporter * exporter)
77-{
78-}
79-
+0,
-33
1@@ -1,33 +0,0 @@
2-/* wld: interface/exporter.h
3- *
4- * Copyright (c) 2013, 2014 Michael Forney
5- *
6- * Permission is hereby granted, free of charge, to any person obtaining a copy
7- * of this software and associated documentation files (the "Software"), to deal
8- * in the Software without restriction, including without limitation the rights
9- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10- * copies of the Software, and to permit persons to whom the Software is
11- * furnished to do so, subject to the following conditions:
12- *
13- * The above copyright notice and this permission notice shall be included in
14- * all copies or substantial portions of the Software.
15- *
16- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22- * SOFTWARE.
23- */
24-
25-static void exporter_destroy(struct wld_exporter * exporter);
26-static bool exporter_export(struct wld_exporter * exporter,
27- struct wld_buffer * buffer,
28- uint32_t type, union wld_object * object);
29-
30-static const struct wld_exporter_impl wld_exporter_impl = {
31- .destroy = &exporter_destroy,
32- .export = &exporter_export
33-};
34-
+24,
-30
1@@ -75,7 +75,6 @@ struct nouveau_buffer
2 #include "interface/buffer.h"
3 #define DRM_DRIVER_NAME nouveau
4 #include "interface/drm.h"
5-#include "interface/exporter.h"
6 IMPL(nouveau_context, wld_context)
7 IMPL(nouveau_renderer, wld_renderer)
8 IMPL(nouveau_buffer, wld_buffer)
9@@ -298,6 +297,29 @@ struct wld_renderer * context_create_renderer(struct wld_context * base)
10 return NULL;
11 }
12
13+static bool export(struct wld_exporter * exporter, struct wld_buffer * base,
14+ uint32_t type, union wld_object * object)
15+{
16+ struct nouveau_buffer * buffer = nouveau_buffer(base);
17+
18+ switch (type)
19+ {
20+ case WLD_DRM_OBJECT_HANDLE:
21+ object->u32 = buffer->bo->handle;
22+ return true;
23+ case WLD_DRM_OBJECT_PRIME_FD:
24+ if (nouveau_bo_set_prime(buffer->bo, &object->i) != 0)
25+ return false;
26+ return true;
27+ case WLD_DRM_OBJECT_GEM_NAME:
28+ if (nouveau_bo_name_get(buffer->bo, &object->u32) != 0)
29+ return false;
30+ return true;
31+ default:
32+ return false;
33+ }
34+}
35+
36 static struct nouveau_buffer * new_buffer(struct nouveau_context * context,
37 uint32_t width, uint32_t height,
38 uint32_t format, uint32_t pitch)
39@@ -310,7 +332,7 @@ static struct nouveau_buffer * new_buffer(struct nouveau_context * context,
40 buffer_initialize(&buffer->base, &wld_buffer_impl,
41 width, height, format, pitch);
42 buffer->context = context;
43- wld_exporter_initialize(&buffer->exporter, &wld_exporter_impl);
44+ buffer->exporter.export = &export;
45 wld_buffer_add_exporter(&buffer->base.base, &buffer->exporter);
46
47 return buffer;
48@@ -658,31 +680,3 @@ void buffer_destroy(struct buffer * base)
49 free(buffer);
50 }
51
52-/**** Exporter ****/
53-bool exporter_export(struct wld_exporter * exporter, struct wld_buffer * base,
54- uint32_t type, union wld_object * object)
55-{
56- struct nouveau_buffer * buffer = nouveau_buffer(base);
57-
58- switch (type)
59- {
60- case WLD_DRM_OBJECT_HANDLE:
61- object->u32 = buffer->bo->handle;
62- return true;
63- case WLD_DRM_OBJECT_PRIME_FD:
64- if (nouveau_bo_set_prime(buffer->bo, &object->i) != 0)
65- return false;
66- return true;
67- case WLD_DRM_OBJECT_GEM_NAME:
68- if (nouveau_bo_name_get(buffer->bo, &object->u32) != 0)
69- return false;
70- return true;
71- default:
72- return false;
73- }
74-}
75-
76-void exporter_destroy(struct wld_exporter * exporter)
77-{
78-}
79-
M
pixman.c
+35,
-33
1@@ -44,9 +44,10 @@ struct pixman_buffer
2 pixman_image_t * image;
3 };
4
5-struct pixman_exporter
6+struct pixman_map
7 {
8- struct wld_exporter base;
9+ struct wld_exporter exporter;
10+ struct wld_destructor destructor;
11 pixman_image_t * image;
12 };
13
14@@ -54,10 +55,8 @@ struct pixman_exporter
15 #define RENDERER_IMPLEMENTS_REGION
16 #include "interface/renderer.h"
17 #include "interface/buffer.h"
18-#include "interface/exporter.h"
19 IMPL(pixman_renderer, wld_renderer)
20 IMPL(pixman_buffer, wld_buffer)
21-IMPL(pixman_exporter, wld_exporter)
22
23 static struct wld_context context = { .impl = &wld_context_impl };
24
25@@ -178,6 +177,31 @@ static void destroy_image(pixman_image_t * image, void * data)
26 wld_unmap(&buffer->base);
27 }
28
29+bool map_export(struct wld_exporter * exporter, struct wld_buffer * buffer,
30+ uint32_t type, union wld_object * object)
31+{
32+ struct pixman_map * map
33+ = CONTAINER_OF(exporter, struct pixman_map, exporter);
34+
35+ switch (type)
36+ {
37+ case WLD_PIXMAN_OBJECT_IMAGE:
38+ object->ptr = pixman_image_ref(map->image);
39+ return true;
40+ default:
41+ return false;
42+ }
43+}
44+
45+void map_destroy(struct wld_destructor * destructor)
46+{
47+ struct pixman_map * map
48+ = CONTAINER_OF(destructor, struct pixman_map, destructor);
49+
50+ pixman_image_unref(map->image);
51+ free(map);
52+}
53+
54 static pixman_image_t * pixman_image(struct buffer * buffer)
55 {
56 if (buffer->base.impl == &wld_buffer_impl)
57@@ -188,7 +212,7 @@ static pixman_image_t * pixman_image(struct buffer * buffer)
58 if (wld_export(&buffer->base, WLD_PIXMAN_OBJECT_IMAGE, &object))
59 return object.ptr;
60
61- struct pixman_exporter * exporter;
62+ struct pixman_map * map;
63 pixman_image_t * image;
64
65 if (!wld_map(&buffer->base))
66@@ -201,12 +225,14 @@ static pixman_image_t * pixman_image(struct buffer * buffer)
67 if (!image)
68 goto error1;
69
70- if (!(exporter = malloc(sizeof *exporter)))
71+ if (!(map = malloc(sizeof *map)))
72 goto error2;
73
74- wld_exporter_initialize(&exporter->base, &wld_exporter_impl);
75- exporter->image = image;
76- wld_buffer_add_exporter(&buffer->base, &exporter->base);
77+ map->image = image;
78+ map->exporter.export = &map_export;
79+ wld_buffer_add_exporter(&buffer->base, &map->exporter);
80+ map->destructor.destroy = &map_destroy;
81+ wld_buffer_add_destructor(&buffer->base, &map->destructor);
82 pixman_image_set_destroy_function(image, &destroy_image, buffer);
83
84 return pixman_image_ref(image);
85@@ -422,27 +448,3 @@ void buffer_destroy(struct buffer * base)
86 free(buffer);
87 }
88
89-/**** Exporter ****/
90-bool exporter_export(struct wld_exporter * base, struct wld_buffer * buffer,
91- uint32_t type, union wld_object * object)
92-{
93- struct pixman_exporter * exporter = pixman_exporter(base);
94-
95- switch (type)
96- {
97- case WLD_PIXMAN_OBJECT_IMAGE:
98- object->ptr = pixman_image_ref(exporter->image);
99- return true;
100- default:
101- return false;
102- }
103-}
104-
105-void exporter_destroy(struct wld_exporter * base)
106-{
107- struct pixman_exporter * exporter = pixman_exporter(base);
108-
109- pixman_image_unref(exporter->image);
110- free(exporter);
111-}
112-
+1,
-4
1@@ -195,7 +195,6 @@ struct buffer * context_create_buffer(struct wld_context * base,
2 {
3 struct drm_context * context = drm_context(base);
4 struct buffer * buffer;
5- struct wld_exporter * exporter;
6 union wld_object object;
7 struct wl_buffer * wl;
8
9@@ -218,11 +217,9 @@ struct buffer * context_create_buffer(struct wld_context * base,
10 if (!wl)
11 goto error1;
12
13- if (!(exporter = wayland_create_exporter(wl)))
14+ if (!wayland_buffer_add_exporter(buffer, wl))
15 goto error2;
16
17- wld_buffer_add_exporter(&buffer->base, exporter);
18-
19 return buffer;
20
21 error2:
+2,
-1
1@@ -26,6 +26,7 @@
2
3 #include "wld.h"
4
5+struct buffer;
6 struct wl_display;
7 struct wl_event_queue;
8 struct wl_buffer;
9@@ -57,7 +58,7 @@ extern const struct wld_wayland_interface wayland_shm_interface;
10 int wayland_roundtrip(struct wl_display * display,
11 struct wl_event_queue * queue);
12
13-struct wld_exporter * wayland_create_exporter(struct wl_buffer * buffer);
14+bool wayland_buffer_add_exporter(struct buffer * buffer, struct wl_buffer * wl);
15
16 #endif
17
+3,
-5
1@@ -164,7 +164,6 @@ struct buffer * context_create_buffer(struct wld_context * base,
2 {
3 struct shm_context * context = shm_context(base);
4 struct shm_buffer * buffer;
5- struct wld_exporter * exporter;
6 char name[] = "/tmp/wld-XXXXXX";
7 uint32_t pitch = width * format_bytes_per_pixel(format);
8 size_t size = pitch * height;
9@@ -195,13 +194,12 @@ struct buffer * context_create_buffer(struct wld_context * base,
10 if (!wl)
11 goto error2;
12
13- if (!(exporter = wayland_create_exporter(wl)))
14- goto error3;
15-
16 buffer_initialize(&buffer->base, &wld_buffer_impl,
17 width, height, format, pitch);
18 buffer->fd = fd;
19- wld_buffer_add_exporter(&buffer->base.base, exporter);
20+
21+ if (!(wayland_buffer_add_exporter(&buffer->base, wl)))
22+ goto error3;
23
24 return &buffer->base;
25
+31,
-27
1@@ -28,10 +28,11 @@
2 #include <stdlib.h>
3 #include <wayland-client.h>
4
5-struct wayland_exporter
6+struct wayland_buffer
7 {
8- struct wld_exporter base;
9- struct wl_buffer * buffer;
10+ struct wld_exporter exporter;
11+ struct wld_destructor destructor;
12+ struct wl_buffer * wl;
13 };
14
15 struct wayland_buffer_socket
16@@ -44,9 +45,6 @@ struct wayland_buffer_socket
17 struct wl_event_queue * queue;
18 };
19
20-#include "interface/exporter.h"
21-IMPL(wayland_exporter, wld_exporter)
22-
23 static bool buffer_socket_attach(struct buffer_socket * socket,
24 struct buffer * buffer);
25 static void buffer_socket_process(struct buffer_socket * socket);
26@@ -205,39 +203,45 @@ int wayland_roundtrip(struct wl_display * display,
27 return ret;
28 }
29
30-struct wld_exporter * wayland_create_exporter(struct wl_buffer * buffer)
31-{
32- struct wayland_exporter * exporter;
33-
34- if (!(exporter = malloc(sizeof *exporter)))
35- return NULL;
36-
37- wld_exporter_initialize(&exporter->base, &wld_exporter_impl);
38- exporter->buffer = buffer;
39-
40- return &exporter->base;
41-}
42-
43-bool exporter_export(struct wld_exporter * base, struct wld_buffer * buffer,
44- uint32_t type, union wld_object * object)
45+static bool buffer_export(struct wld_exporter * exporter,
46+ struct wld_buffer * buffer,
47+ uint32_t type, union wld_object * object)
48 {
49- struct wayland_exporter * exporter = wayland_exporter(base);
50+ struct wayland_buffer * wayland_buffer
51+ = CONTAINER_OF(exporter, struct wayland_buffer, exporter);
52
53 switch (type)
54 {
55 case WLD_WAYLAND_OBJECT_BUFFER:
56- object->ptr = exporter->buffer;
57+ object->ptr = wayland_buffer->wl;
58 return true;
59 default: return false;
60 }
61 }
62
63-void exporter_destroy(struct wld_exporter * base)
64+static void buffer_destroy(struct wld_destructor * destructor)
65 {
66- struct wayland_exporter * exporter = wayland_exporter(base);
67+ struct wayland_buffer * wayland_buffer
68+ = CONTAINER_OF(destructor, struct wayland_buffer, destructor);
69
70- wl_buffer_destroy(exporter->buffer);
71- free(exporter);
72+ wl_buffer_destroy(wayland_buffer->wl);
73+ free(wayland_buffer);
74+}
75+
76+bool wayland_buffer_add_exporter(struct buffer * buffer, struct wl_buffer * wl)
77+{
78+ struct wayland_buffer * wayland_buffer;
79+
80+ if (!(wayland_buffer = malloc(sizeof *wayland_buffer)))
81+ return false;
82+
83+ wayland_buffer->wl = wl;
84+ wayland_buffer->exporter.export = &buffer_export;
85+ wld_buffer_add_exporter(&buffer->base, &wayland_buffer->exporter);
86+ wayland_buffer->destructor.destroy = &buffer_destroy;
87+ wld_buffer_add_destructor(&buffer->base, &wayland_buffer->destructor);
88+
89+ return true;
90 }
91
92 bool buffer_socket_attach(struct buffer_socket * base, struct buffer * buffer)
+1,
-0
1@@ -127,6 +127,7 @@ struct buffer
2
3 unsigned references, map_references;
4 struct wld_exporter * exporters;
5+ struct wld_destructor * destructors;
6 };
7
8 struct wld_buffer_impl
M
wld.h
+8,
-8
1@@ -157,20 +157,17 @@ static inline void wld_font_text_extents(struct wld_font * font,
2
3 struct wld_exporter
4 {
5- const struct wld_exporter_impl * const impl;
6+ bool (* export)(struct wld_exporter * exporter, struct wld_buffer * buffer,
7+ uint32_t type, union wld_object * object);
8 struct wld_exporter * next;
9 };
10
11-struct wld_exporter_impl
12+struct wld_destructor
13 {
14- bool (* export)(struct wld_exporter * exporter, struct wld_buffer * buffer,
15- uint32_t type, union wld_object * object);
16- void (* destroy)(struct wld_exporter * exporter);
17+ void (* destroy)(struct wld_destructor * destructor);
18+ struct wld_destructor * next;
19 };
20
21-void wld_exporter_initialize(struct wld_exporter * exporter,
22- const struct wld_exporter_impl * impl);
23-
24 struct wld_buffer
25 {
26 const struct wld_buffer_impl * const impl;
27@@ -190,6 +187,9 @@ bool wld_export(struct wld_buffer * buffer,
28 void wld_buffer_add_exporter(struct wld_buffer * buffer,
29 struct wld_exporter * exporter);
30
31+void wld_buffer_add_destructor(struct wld_buffer * buffer,
32+ struct wld_destructor * destructor);
33+
34 /**
35 * Increase the reference count of a buffer.
36 */