~ubuntu-branches/ubuntu/oneiric/isc-dhcp/oneiric-security

« back to all changes in this revision

Viewing changes to includes/isc-dhcp/mem.h

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Pollock
  • Date: 2009-09-02 22:34:25 UTC
  • Revision ID: james.westby@ubuntu.com-20090902223425-nypo7bkftxffq41m
Tags: upstream-4.1.0
ImportĀ upstreamĀ versionĀ 4.1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
 
3
 * Copyright (C) 1997-2001  Internet Software Consortium.
 
4
 *
 
5
 * Permission to use, copy, modify, and/or distribute this software for any
 
6
 * purpose with or without fee is hereby granted, provided that the above
 
7
 * copyright notice and this permission notice appear in all copies.
 
8
 *
 
9
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
 
10
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 
11
 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
 
12
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 
13
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 
14
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 
15
 * PERFORMANCE OF THIS SOFTWARE.
 
16
 */
 
17
 
 
18
/* $Id: mem.h,v 1.2 2007/11/16 11:04:11 shane Exp $ */
 
19
 
 
20
#ifndef ISC_MEM_H
 
21
#define ISC_MEM_H 1
 
22
 
 
23
/*! \file isc/mem.h */
 
24
 
 
25
#include <stdio.h>
 
26
 
 
27
#include <isc-dhcp/lang.h>
 
28
/*#include <isc-dhcp/mutex.h>*/
 
29
/*#include <isc-dhcp/platform.h>*/
 
30
#include <isc-dhcp/types.h>
 
31
/*#include <isc-dhcp/xml.h>*/
 
32
#include <isc-dhcp/result.h>
 
33
 
 
34
ISC_LANG_BEGINDECLS
 
35
 
 
36
#define ISC_MEM_LOWATER 0
 
37
#define ISC_MEM_HIWATER 1
 
38
typedef void (*isc_mem_water_t)(void *, int);
 
39
 
 
40
typedef void * (*isc_memalloc_t)(void *, size_t);
 
41
typedef void (*isc_memfree_t)(void *, void *);
 
42
 
 
43
/*%
 
44
 * Define ISC_MEM_DEBUG=1 to make all functions that free memory
 
45
 * set the pointer being freed to NULL after being freed.
 
46
 * This is the default; set ISC_MEM_DEBUG=0 to disable it.
 
47
 */
 
48
#ifndef ISC_MEM_DEBUG
 
49
#define ISC_MEM_DEBUG 1
 
50
#endif
 
51
 
 
52
/*%
 
53
 * Define ISC_MEM_TRACKLINES=1 to turn on detailed tracing of memory
 
54
 * allocation and freeing by file and line number.
 
55
 */
 
56
#ifndef ISC_MEM_TRACKLINES
 
57
#define ISC_MEM_TRACKLINES 1
 
58
#endif
 
59
 
 
60
/*%
 
61
 * Define ISC_MEM_CHECKOVERRUN=1 to turn on checks for using memory outside
 
62
 * the requested space.  This will increase the size of each allocation.
 
63
 */
 
64
#ifndef ISC_MEM_CHECKOVERRUN
 
65
#define ISC_MEM_CHECKOVERRUN 1
 
66
#endif
 
67
 
 
68
/*%
 
69
 * Define ISC_MEM_FILL=1 to fill each block of memory returned to the system
 
70
 * with the byte string '0xbe'.  This helps track down uninitialized pointers
 
71
 * and the like.  On freeing memory, the space is filled with '0xde' for
 
72
 * the same reasons.
 
73
 */
 
74
#ifndef ISC_MEM_FILL
 
75
#define ISC_MEM_FILL 1
 
76
#endif
 
77
 
 
78
/*%
 
79
 * Define ISC_MEMPOOL_NAMES=1 to make memory pools store a symbolic
 
80
 * name so that the leaking pool can be more readily identified in
 
81
 * case of a memory leak.
 
82
 */
 
83
#ifndef ISC_MEMPOOL_NAMES
 
84
#define ISC_MEMPOOL_NAMES 1
 
85
#endif
 
86
 
 
87
extern unsigned int isc_mem_debugging;
 
88
/*@{*/
 
89
#define ISC_MEM_DEBUGTRACE              0x00000001U
 
90
#define ISC_MEM_DEBUGRECORD             0x00000002U
 
91
#define ISC_MEM_DEBUGUSAGE              0x00000004U
 
92
#define ISC_MEM_DEBUGSIZE               0x00000008U
 
93
#define ISC_MEM_DEBUGCTX                0x00000010U
 
94
#define ISC_MEM_DEBUGALL                0x0000001FU
 
95
/*!<
 
96
 * The variable isc_mem_debugging holds a set of flags for
 
97
 * turning certain memory debugging options on or off at
 
98
 * runtime.  Its is intialized to the value ISC_MEM_DEGBUGGING,
 
99
 * which is 0 by default but may be overridden at compile time.
 
100
 * The following flags can be specified:
 
101
 *
 
102
 * \li #ISC_MEM_DEBUGTRACE
 
103
 *      Log each allocation and free to isc_lctx.
 
104
 *
 
105
 * \li #ISC_MEM_DEBUGRECORD
 
106
 *      Remember each allocation, and match them up on free.
 
107
 *      Crash if a free doesn't match an allocation.
 
108
 *
 
109
 * \li #ISC_MEM_DEBUGUSAGE
 
110
 *      If a hi_water mark is set, print the maximium inuse memory
 
111
 *      every time it is raised once it exceeds the hi_water mark.
 
112
 *
 
113
 * \li #ISC_MEM_DEBUGSIZE
 
114
 *      Check the size argument being passed to isc_mem_put() matches
 
115
 *      that passed to isc_mem_get().
 
116
 *
 
117
 * \li #ISC_MEM_DEBUGCTX
 
118
 *      Check the mctx argument being passed to isc_mem_put() matches
 
119
 *      that passed to isc_mem_get().
 
120
 */
 
121
/*@}*/
 
122
 
 
123
#if ISC_MEM_TRACKLINES
 
124
#define _ISC_MEM_FILELINE       , __FILE__, __LINE__
 
125
#define _ISC_MEM_FLARG          , const char *, int
 
126
#else
 
127
#define _ISC_MEM_FILELINE
 
128
#define _ISC_MEM_FLARG
 
129
#endif
 
130
 
 
131
/*!
 
132
 * Define ISC_MEM_USE_INTERNAL_MALLOC=1 to use the internal malloc()
 
133
 * implementation in preference to the system one.  The internal malloc()
 
134
 * is very space-efficient, and quite fast on uniprocessor systems.  It
 
135
 * performs poorly on multiprocessor machines.
 
136
 * JT: we can overcome the performance issue on multiprocessor machines
 
137
 * by carefully separating memory contexts.
 
138
 */
 
139
 
 
140
#ifndef ISC_MEM_USE_INTERNAL_MALLOC
 
141
#define ISC_MEM_USE_INTERNAL_MALLOC 1
 
142
#endif
 
143
 
 
144
/*
 
145
 * Flags for isc_mem_create2()calls.
 
146
 */
 
147
#define ISC_MEMFLAG_NOLOCK      0x00000001       /* no lock is necessary */
 
148
#define ISC_MEMFLAG_INTERNAL    0x00000002       /* use internal malloc */
 
149
#if ISC_MEM_USE_INTERNAL_MALLOC
 
150
#define ISC_MEMFLAG_DEFAULT     ISC_MEMFLAG_INTERNAL
 
151
#else
 
152
#define ISC_MEMFLAG_DEFAULT     0
 
153
#endif
 
154
 
 
155
 
 
156
#define isc_mem_get(c, s)       isc__mem_get((c), (s) _ISC_MEM_FILELINE)
 
157
#define isc_mem_allocate(c, s)  isc__mem_allocate((c), (s) _ISC_MEM_FILELINE)
 
158
#define isc_mem_strdup(c, p)    isc__mem_strdup((c), (p) _ISC_MEM_FILELINE)
 
159
#define isc_mempool_get(c)      isc__mempool_get((c) _ISC_MEM_FILELINE)
 
160
 
 
161
/*% 
 
162
 * isc_mem_putanddetach() is a convienence function for use where you
 
163
 * have a structure with an attached memory context.
 
164
 *
 
165
 * Given:
 
166
 *
 
167
 * \code
 
168
 * struct {
 
169
 *      ...
 
170
 *      isc_mem_t *mctx;
 
171
 *      ...
 
172
 * } *ptr;
 
173
 *
 
174
 * isc_mem_t *mctx;
 
175
 *
 
176
 * isc_mem_putanddetach(&ptr->mctx, ptr, sizeof(*ptr));
 
177
 * \endcode
 
178
 *
 
179
 * is the equivalent of:
 
180
 *
 
181
 * \code
 
182
 * mctx = NULL;
 
183
 * isc_mem_attach(ptr->mctx, &mctx);
 
184
 * isc_mem_detach(&ptr->mctx);
 
185
 * isc_mem_put(mctx, ptr, sizeof(*ptr));
 
186
 * isc_mem_detach(&mctx);
 
187
 * \endcode
 
188
 */
 
189
 
 
190
#if ISC_MEM_DEBUG
 
191
#define isc_mem_put(c, p, s) \
 
192
        do { \
 
193
                isc__mem_put((c), (p), (s) _ISC_MEM_FILELINE); \
 
194
                (p) = NULL; \
 
195
        } while (0)
 
196
#define isc_mem_putanddetach(c, p, s) \
 
197
        do { \
 
198
                isc__mem_putanddetach((c), (p), (s) _ISC_MEM_FILELINE); \
 
199
                (p) = NULL; \
 
200
        } while (0)
 
201
#define isc_mem_free(c, p) \
 
202
        do { \
 
203
                isc__mem_free((c), (p) _ISC_MEM_FILELINE); \
 
204
                (p) = NULL; \
 
205
        } while (0)
 
206
#define isc_mempool_put(c, p) \
 
207
        do { \
 
208
                isc__mempool_put((c), (p) _ISC_MEM_FILELINE); \
 
209
                (p) = NULL; \
 
210
        } while (0)
 
211
#else
 
212
#define isc_mem_put(c, p, s)    isc__mem_put((c), (p), (s) _ISC_MEM_FILELINE)
 
213
#define isc_mem_putanddetach(c, p, s) \
 
214
        isc__mem_putanddetach((c), (p), (s) _ISC_MEM_FILELINE)
 
215
#define isc_mem_free(c, p)      isc__mem_free((c), (p) _ISC_MEM_FILELINE)
 
216
#define isc_mempool_put(c, p)   isc__mempool_put((c), (p) _ISC_MEM_FILELINE)
 
217
#endif
 
218
 
 
219
/*@{*/
 
220
isc_result_t 
 
221
isc_mem_create(size_t max_size, size_t target_size,
 
222
               isc_mem_t **mctxp);
 
223
 
 
224
isc_result_t
 
225
isc_mem_create2(size_t max_size, size_t target_size,
 
226
                isc_mem_t **mctxp, unsigned int flags);
 
227
 
 
228
isc_result_t 
 
229
isc_mem_createx(size_t max_size, size_t target_size,
 
230
                isc_memalloc_t memalloc, isc_memfree_t memfree,
 
231
                void *arg, isc_mem_t **mctxp);
 
232
 
 
233
isc_result_t 
 
234
isc_mem_createx2(size_t max_size, size_t target_size,
 
235
                 isc_memalloc_t memalloc, isc_memfree_t memfree,
 
236
                 void *arg, isc_mem_t **mctxp, unsigned int flags);
 
237
 
 
238
/*!<
 
239
 * \brief Create a memory context.
 
240
 *
 
241
 * 'max_size' and 'target_size' are tuning parameters.  When
 
242
 * ISC_MEMFLAG_INTERNAL is set, allocations smaller than 'max_size'
 
243
 * will be satisfied by getting blocks of size 'target_size' from the
 
244
 * system allocator and breaking them up into pieces; larger allocations
 
245
 * will use the system allocator directly. If 'max_size' and/or
 
246
 * 'target_size' are zero, default values will be * used.  When
 
247
 * ISC_MEMFLAG_INTERNAL is not set, 'target_size' is ignored.
 
248
 *
 
249
 * 'max_size' is also used to size the statistics arrays and the array
 
250
 * used to record active memory when ISC_MEM_DEBUGRECORD is set.  Settin
 
251
 * 'max_size' too low can have detrimental effects on performance.
 
252
 *
 
253
 * A memory context created using isc_mem_createx() will obtain
 
254
 * memory from the system by calling 'memalloc' and 'memfree',
 
255
 * passing them the argument 'arg'.  A memory context created
 
256
 * using isc_mem_create() will use the standard library malloc()
 
257
 * and free().
 
258
 *
 
259
 * If ISC_MEMFLAG_NOLOCK is set in 'flags', the corresponding memory context
 
260
 * will be accessed without locking.  The user who creates the context must
 
261
 * ensure there be no race.  Since this can be a source of bug, it is generally
 
262
 * inadvisable to use this flag unless the user is very sure about the race
 
263
 * condition and the access to the object is highly performance sensitive.
 
264
 *
 
265
 * Requires:
 
266
 * mctxp != NULL && *mctxp == NULL */
 
267
/*@}*/
 
268
 
 
269
/*@{*/
 
270
void 
 
271
isc_mem_attach(isc_mem_t *, isc_mem_t **);
 
272
void 
 
273
isc_mem_detach(isc_mem_t **);
 
274
/*!<
 
275
 * \brief Attach to / detach from a memory context.
 
276
 *
 
277
 * This is intended for applications that use multiple memory contexts
 
278
 * in such a way that it is not obvious when the last allocations from
 
279
 * a given context has been freed and destroying the context is safe.
 
280
 * 
 
281
 * Most applications do not need to call these functions as they can
 
282
 * simply create a single memory context at the beginning of main()
 
283
 * and destroy it at the end of main(), thereby guaranteeing that it
 
284
 * is not destroyed while there are outstanding allocations.
 
285
 */
 
286
/*@}*/
 
287
 
 
288
void 
 
289
isc_mem_destroy(isc_mem_t **);
 
290
/*%<
 
291
 * Destroy a memory context.
 
292
 */
 
293
 
 
294
isc_result_t 
 
295
isc_mem_ondestroy(isc_mem_t *ctx,
 
296
                  isc_task_t *task,
 
297
                  isc_event_t **event);
 
298
/*%<
 
299
 * Request to be notified with an event when a memory context has
 
300
 * been successfully destroyed.
 
301
 */
 
302
 
 
303
void 
 
304
isc_mem_stats(isc_mem_t *mctx, FILE *out);
 
305
/*%<
 
306
 * Print memory usage statistics for 'mctx' on the stream 'out'.
 
307
 */
 
308
 
 
309
void 
 
310
isc_mem_setdestroycheck(isc_mem_t *mctx,
 
311
                        isc_boolean_t on);
 
312
/*%<
 
313
 * If 'on' is ISC_TRUE, 'mctx' will check for memory leaks when
 
314
 * destroyed and abort the program if any are present.
 
315
 */
 
316
 
 
317
/*@{*/
 
318
void 
 
319
isc_mem_setquota(isc_mem_t *, size_t);
 
320
size_t 
 
321
isc_mem_getquota(isc_mem_t *);
 
322
/*%<
 
323
 * Set/get the memory quota of 'mctx'.  This is a hard limit
 
324
 * on the amount of memory that may be allocated from mctx;
 
325
 * if it is exceeded, allocations will fail.
 
326
 */
 
327
/*@}*/
 
328
 
 
329
size_t 
 
330
isc_mem_inuse(isc_mem_t *mctx);
 
331
/*%<
 
332
 * Get an estimate of the number of memory in use in 'mctx', in bytes.
 
333
 * This includes quantization overhead, but does not include memory
 
334
 * allocated from the system but not yet used.
 
335
 */
 
336
 
 
337
void
 
338
isc_mem_setwater(isc_mem_t *mctx, isc_mem_water_t water, void *water_arg,
 
339
                 size_t hiwater, size_t lowater);
 
340
/*%<
 
341
 * Set high and low water marks for this memory context.  
 
342
 * 
 
343
 * When the memory
 
344
 * usage of 'mctx' exceeds 'hiwater', '(water)(water_arg, #ISC_MEM_HIWATER)'
 
345
 * will be called.  When the usage drops below 'lowater', 'water' will
 
346
 * again be called, this time with #ISC_MEM_LOWATER.
 
347
 *
 
348
 * If 'water' is NULL then 'water_arg', 'hi_water' and 'lo_water' are
 
349
 * ignored and the state is reset.
 
350
 *
 
351
 * Requires:
 
352
 *
 
353
 *      'water' is not NULL.
 
354
 *      hi_water >= lo_water
 
355
 */
 
356
 
 
357
void
 
358
isc_mem_printactive(isc_mem_t *mctx, FILE *file);
 
359
/*%<
 
360
 * Print to 'file' all active memory in 'mctx'.
 
361
 *
 
362
 * Requires ISC_MEM_DEBUGRECORD to have been set.
 
363
 */
 
364
 
 
365
void
 
366
isc_mem_printallactive(FILE *file);
 
367
/*%<
 
368
 * Print to 'file' all active memory in all contexts.
 
369
 *
 
370
 * Requires ISC_MEM_DEBUGRECORD to have been set.
 
371
 */
 
372
 
 
373
void
 
374
isc_mem_checkdestroyed(FILE *file);
 
375
/*%<
 
376
 * Check that all memory contexts have been destroyed.
 
377
 * Prints out those that have not been.
 
378
 * Fatally fails if there are still active contexts.
 
379
 */
 
380
 
 
381
/*
 
382
 * Memory pools
 
383
 */
 
384
 
 
385
isc_result_t
 
386
isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp);
 
387
/*%<
 
388
 * Create a memory pool.
 
389
 *
 
390
 * Requires:
 
391
 *\li   mctx is a valid memory context.
 
392
 *\li   size > 0
 
393
 *\li   mpctxp != NULL and *mpctxp == NULL
 
394
 *
 
395
 * Defaults:
 
396
 *\li   maxalloc = UINT_MAX
 
397
 *\li   freemax = 1
 
398
 *\li   fillcount = 1
 
399
 *
 
400
 * Returns:
 
401
 *\li   #ISC_R_NOMEMORY         -- not enough memory to create pool
 
402
 *\li   #ISC_R_SUCCESS          -- all is well.
 
403
 */
 
404
 
 
405
void
 
406
isc_mempool_destroy(isc_mempool_t **mpctxp);
 
407
/*%<
 
408
 * Destroy a memory pool.
 
409
 *
 
410
 * Requires:
 
411
 *\li   mpctxp != NULL && *mpctxp is a valid pool.
 
412
 *\li   The pool has no un"put" allocations outstanding
 
413
 */
 
414
 
 
415
void
 
416
isc_mempool_setname(isc_mempool_t *mpctx, const char *name);
 
417
/*%<
 
418
 * Associate a name with a memory pool.  At most 15 characters may be used.
 
419
 *
 
420
 * Requires:
 
421
 *\li   mpctx is a valid pool.
 
422
 *\li   name != NULL;
 
423
 */
 
424
 
 
425
/*
 
426
void
 
427
isc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock);
 
428
*/
 
429
/*%<
 
430
 * Associate a lock with this memory pool.
 
431
 *
 
432
 * This lock is used when getting or putting items using this memory pool,
 
433
 * and it is also used to set or get internal state via the isc_mempool_get*()
 
434
 * and isc_mempool_set*() set of functions.
 
435
 *
 
436
 * Mutiple pools can each share a single lock.  For instance, if "manager"
 
437
 * type object contained pools for various sizes of events, and each of
 
438
 * these pools used a common lock.  Note that this lock must NEVER be used
 
439
 * by other than mempool routines once it is given to a pool, since that can
 
440
 * easily cause double locking.
 
441
 *
 
442
 * Requires:
 
443
 *
 
444
 *\li   mpctpx is a valid pool.
 
445
 *
 
446
 *\li   lock != NULL.
 
447
 *
 
448
 *\li   No previous lock is assigned to this pool.
 
449
 *
 
450
 *\li   The lock is initialized before calling this function via the normal
 
451
 *      means of doing that.
 
452
 */
 
453
 
 
454
/*
 
455
 * The following functions get/set various parameters.  Note that due to
 
456
 * the unlocked nature of pools these are potentially random values unless
 
457
 * the imposed externally provided locking protocols are followed.
 
458
 *
 
459
 * Also note that the quota limits will not always take immediate effect.
 
460
 * For instance, setting "maxalloc" to a number smaller than the currently
 
461
 * allocated count is permitted.  New allocations will be refused until
 
462
 * the count drops below this threshold.
 
463
 *
 
464
 * All functions require (in addition to other requirements):
 
465
 *      mpctx is a valid memory pool
 
466
 */
 
467
 
 
468
unsigned int
 
469
isc_mempool_getfreemax(isc_mempool_t *mpctx);
 
470
/*%<
 
471
 * Returns the maximum allowed size of the free list.
 
472
 */
 
473
 
 
474
void
 
475
isc_mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit);
 
476
/*%<
 
477
 * Sets the maximum allowed size of the free list.
 
478
 */
 
479
 
 
480
unsigned int
 
481
isc_mempool_getfreecount(isc_mempool_t *mpctx);
 
482
/*%<
 
483
 * Returns current size of the free list.
 
484
 */
 
485
 
 
486
unsigned int
 
487
isc_mempool_getmaxalloc(isc_mempool_t *mpctx);
 
488
/*!<
 
489
 * Returns the maximum allowed number of allocations.
 
490
 */
 
491
 
 
492
void
 
493
isc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit);
 
494
/*%<
 
495
 * Sets the maximum allowed number of allocations.
 
496
 *
 
497
 * Additional requirements:
 
498
 *\li   limit > 0
 
499
 */
 
500
 
 
501
unsigned int
 
502
isc_mempool_getallocated(isc_mempool_t *mpctx);
 
503
/*%<
 
504
 * Returns the number of items allocated from this pool.
 
505
 */
 
506
 
 
507
unsigned int
 
508
isc_mempool_getfillcount(isc_mempool_t *mpctx);
 
509
/*%<
 
510
 * Returns the number of items allocated as a block from the parent memory
 
511
 * context when the free list is empty.
 
512
 */
 
513
 
 
514
void
 
515
isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit);
 
516
/*%<
 
517
 * Sets the fillcount.
 
518
 *
 
519
 * Additional requirements:
 
520
 *\li   limit > 0
 
521
 */
 
522
 
 
523
 
 
524
/*
 
525
 * Pseudo-private functions for use via macros.  Do not call directly.
 
526
 */
 
527
void *          
 
528
isc__mem_get(isc_mem_t *, size_t _ISC_MEM_FLARG);
 
529
void            
 
530
isc__mem_putanddetach(isc_mem_t **, void *,
 
531
                                      size_t _ISC_MEM_FLARG);
 
532
void            
 
533
isc__mem_put(isc_mem_t *, void *, size_t _ISC_MEM_FLARG);
 
534
void *          
 
535
isc__mem_allocate(isc_mem_t *, size_t _ISC_MEM_FLARG);
 
536
void            
 
537
isc__mem_free(isc_mem_t *, void * _ISC_MEM_FLARG);
 
538
char *          
 
539
isc__mem_strdup(isc_mem_t *, const char *_ISC_MEM_FLARG);
 
540
void *          
 
541
isc__mempool_get(isc_mempool_t * _ISC_MEM_FLARG);
 
542
void            
 
543
isc__mempool_put(isc_mempool_t *, void * _ISC_MEM_FLARG);
 
544
 
 
545
#ifdef HAVE_LIBXML2
 
546
void
 
547
isc_mem_renderxml(isc_mem_t *mgr, xmlTextWriterPtr writer);
 
548
#endif /* HAVE_LIBXML2 */
 
549
 
 
550
ISC_LANG_ENDDECLS
 
551
 
 
552
#endif /* ISC_MEM_H */