talloc: talloc_set_flag/talloc_unset_flag and TALLOC_FLAG_WARN_MAY_REFERENCE
[rusty/samba.git] / lib / talloc / talloc.h
index edd9b8ae88a309bb38b81e24e7a7ae027743abaa..956dd4cdd860b177ddcbb2b6aa19671e5da37e86 100644 (file)
 #include <stdio.h>
 #include <stdarg.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * @defgroup talloc The talloc API
  *
@@ -39,7 +43,7 @@
  */
 
 #define TALLOC_VERSION_MAJOR 2
-#define TALLOC_VERSION_MINOR 0
+#define TALLOC_VERSION_MINOR 1
 
 int talloc_version_major(void);
 int talloc_version_minor(void);
@@ -158,20 +162,22 @@ void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
 /**
  * @brief Free a chunk of talloc memory.
  *
- * This function frees a piece of talloc memory, and all its children. It
- * operates recursively on its children. You can call talloc_free() on any
- * pointer returned by talloc().
- *
- * If this pointer has an additional parent when talloc_free() is called then
- * the memory is not actually released, but instead the most recently
- * established parent is destroyed. See talloc_reference() for details on
- * establishing additional parents.
- *
- * For more control on which parent is removed, see talloc_unlink().
- *
- * From the 2.0 version of talloc, as a special case, talloc_free() is
- * refused on pointers that have more than one parent, as talloc would
- * have no way of knowing which parent should be removed. To free a
+ * The talloc_free() function frees a piece of talloc memory, and all its
+ * children. You can call talloc_free() on any pointer returned by
+ * talloc().
+ *
+ * The return value of talloc_free() indicates success or failure, with 0
+ * returned for success and -1 for failure. A possible failure condition
+ * is if the pointer had a destructor attached to it and the destructor
+ * returned -1. See talloc_set_destructor() for details on
+ * destructors. Likewise, if "ptr" is NULL, then the function will make
+ * no modifications and return -1.
+ *
+ * From version 2.0 and onwards, as a special case, talloc_free() is
+ * refused on pointers that have more than one parent associated, as talloc
+ * would have no way of knowing which parent should be removed. This is
+ * different from older versions in the sense that always the reference to
+ * the most recently established parent has been destroyed. Hence to free a
  * pointer that has more than one parent please use talloc_unlink().
  *
  * To help you find problems in your code caused by this behaviour, if
@@ -188,11 +194,15 @@ void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
  * talloc_set_log_stderr() for more information on talloc logging
  * functions.
  *
+ * talloc_free() operates recursively on its children.
+ *
  * @param[in]  ptr      The chunk to be freed.
  *
- * @return              Returns 0 on success and -1 on error. The only possible
+ * @return              Returns 0 on success and -1 on error. A possible
  *                      failure condition is if the pointer had a destructor
- *                      attached to it and the destructor returned -1.
+ *                      attached to it and the destructor returned -1. Likewise,
+ *                      if "ptr" is NULL, then the function will make no
+ *                      modifications and returns -1.
  *
  * Example:
  * @code
@@ -218,7 +228,10 @@ int _talloc_free(void *ptr, const char *location);
  * The function walks along the list of all children of a talloc context and
  * talloc_free()s only the children, not the context itself.
  *
- * @param[in]  ptr      The chunk that you want to free the children of.
+ * A NULL argument is handled as no-op.
+ *
+ * @param[in]  ptr      The chunk that you want to free the children of
+ *                      (NULL is allowed too)
  */
 void talloc_free_children(void *ptr);
 
@@ -387,14 +400,14 @@ const char *talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIB
  *
  * @param[in]  new_ctx  The new parent context.
  *
- * @param[in]  ptr      Pointer to the talloc chunk to move.
+ * @param[in]  pptr     Pointer to the talloc chunk to move.
  *
  * @return              The pointer of the talloc chunk it has been moved to,
  *                      NULL on error.
  */
-void *talloc_move(const void *new_ctx, const void *ptr);
+void *talloc_move(const void *new_ctx, void **pptr);
 #else
-#define talloc_move(ctx, ptr) (_TALLOC_TYPEOF(*(ptr)))_talloc_move((ctx),(void *)(ptr))
+#define talloc_move(ctx, pptr) (_TALLOC_TYPEOF(*(pptr)))_talloc_move((ctx),(void *)(pptr))
 void *_talloc_move(const void *new_ctx, const void *pptr);
 #endif
 
@@ -520,7 +533,7 @@ void *talloc_ptrtype(const void *ctx, #type);
  * @brief Allocate a new 0-sized talloc chunk.
  *
  * This is a utility macro that creates a new memory context hanging off an
- * exiting context, automatically naming it "talloc_new: __location__" where
+ * existing context, automatically naming it "talloc_new: __location__" where
  * __location__ is the source line it is called from. It is particularly
  * useful for creating a new temporary working context.
  *
@@ -687,9 +700,9 @@ void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name
 /**
  * @brief Assign a type to a talloc chunk.
  *
- * This macro allows you to force the name of a pointer to be a particular type.
- * This can be used in conjunction with talloc_get_type() to do type checking on
- * void* pointers.
+ * This macro allows you to force the name of a pointer to be of a particular
+ * type. This can be used in conjunction with talloc_get_type() to do type
+ * checking on void* pointers.
  *
  * It is equivalent to this:
  *
@@ -720,7 +733,7 @@ void talloc_set_type(const char *ptr, #type);
  *
  * @return              The properly casted pointer given by ptr, NULL on error.
  */
-void *talloc_get_name(const void *ptr, #type);
+type *talloc_get_type(const void *ptr, #type);
 #else
 #define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type)
 #define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type)
@@ -890,9 +903,9 @@ size_t talloc_reference_count(const void *ptr);
  *   will reduce the number of parents of this pointer by 1, and will
  *   cause this pointer to be freed if it runs out of parents.
  *
- * - you can talloc_free() the pointer itself. That will destroy the
- *   most recently established parent to the pointer and leave the
- *   pointer as a child of its current parent.
+ * - you can talloc_free() the pointer itself if it has at maximum one
+ *   parent. This behaviour has been changed since the release of version
+ *   2.0. Further informations in the description of "talloc_free".
  *
  * For more control on which parent to remove, see talloc_unlink()
  * @param[in]  ctx      The additional parent.
@@ -920,6 +933,32 @@ void *talloc_reference(const void *ctx, const void *ptr);
 void *_talloc_reference_loc(const void *context, const void *ptr, const char *location);
 #endif
 
+/**
+ * @brief Mark a talloc pointer as being referencable.
+ *
+ * The talloc_may_reference() function marks ptr as having future
+ * references.  As referenced (aka multi-parent) objects need to be
+ * handled differently, this helps debugging: you will get a warning
+ * from talloc_steal() and talloc_free() even if there is only a
+ * single (or NULL) parent.
+ *
+ * It will also warn on talloc_parent() or talloc_parent_name() on
+ * such pointers.
+ *
+ * @param[in]  ptr      The pointer you may create an additional parent for.
+ *
+ * Example:
+ * @code
+ *      unsigned int *a;
+ *     // We may reference this later; be careful!
+ *      a = talloc(NULL, unsigned int);
+ *     talloc_may_reference(a);
+ * @endcode
+ *
+ * @see talloc_reference(), talloc_set_flag()
+ */
+void *talloc_may_reference(const void *ptr);
+
 /**
  * @brief Remove a specific parent from a talloc chunk.
  *
@@ -927,9 +966,10 @@ void *_talloc_reference_loc(const void *context, const void *ptr, const char *lo
  * either be a context used in talloc_reference() with this pointer, or must be
  * a direct parent of ptr.
  *
- * Usually you can just use talloc_free() instead of talloc_unlink(), but
- * sometimes it is useful to have the additional control on which parent is
- * removed.
+ * You can just use talloc_free() instead of talloc_unlink() if there
+ * is at maximum one parent. This behaviour has been changed since the
+ * release of version 2.0. Further informations in the description of
+ * "talloc_free".
  *
  * @param[in]  context  The talloc parent to remove.
  *
@@ -961,6 +1001,15 @@ int talloc_unlink(const void *context, void *ptr);
  * which will be automatically freed on program exit. This can be used
  * to reduce the noise in memory leak reports.
  *
+ * Never use this in code that might be used in objects loaded with
+ * dlopen and unloaded with dlclose. talloc_autofree_context()
+ * internally uses atexit(3). Some platforms like modern Linux handles
+ * this fine, but for example FreeBSD does not deal well with dlopen()
+ * and atexit() used simultaneously: dlclose() does not clean up the
+ * list of atexit-handlers, so when the program exits the code that
+ * was registered from within talloc_autofree_context() is gone, the
+ * program crashes at exit.
+ *
  * @return              A talloc context, NULL on error.
  */
 void *talloc_autofree_context(void);
@@ -968,7 +1017,7 @@ void *talloc_autofree_context(void);
 /**
  * @brief Get the size of a talloc chunk.
  *
- * This function lets you know the amount of memory alloced so far by
+ * This function lets you know the amount of memory allocated so far by
  * this context. It does NOT account for subcontext memory.
  * This can be used to calculate the size of an array.
  *
@@ -1061,7 +1110,7 @@ void *talloc_reparent(const void *old_parent, const void *new_parent, const void
  * @endcode
  *
  * @see talloc()
- * @see talloc_array_zero()
+ * @see talloc_zero_array()
  */
 void *talloc_array(const void *ctx, #type, unsigned count);
 #else
@@ -1265,7 +1314,31 @@ void *talloc_realloc_fn(const void *context, void *ptr, size_t size);
  * @return              The duplicated string, NULL on error.
  */
 char *talloc_strdup(const void *t, const char *p);
+
+/**
+ * @brief Append a string to given string and duplicate the result.
+ *
+ * @param[in]  s        The destination to append to.
+ *
+ * @param[in]  a        The string you want to append.
+ *
+ * @return              The duplicated string, NULL on error.
+ *
+ * @see talloc_strdup()
+ */
 char *talloc_strdup_append(char *s, const char *a);
+
+/**
+ * @brief Append a string to a given buffer and duplicate the result.
+ *
+ * @param[in]  s        The destination buffer to append to.
+ *
+ * @param[in]  a        The string you want to append.
+ *
+ * @return              The duplicated string, NULL on error.
+ *
+ * @see talloc_strdup()
+ */
 char *talloc_strdup_append_buffer(char *s, const char *a);
 
 /**
@@ -1289,7 +1362,39 @@ char *talloc_strdup_append_buffer(char *s, const char *a);
  * @return              The duplicated string, NULL on error.
  */
 char *talloc_strndup(const void *t, const char *p, size_t n);
+
+/**
+ * @brief Append at most n characters of a string to given string and duplicate
+ *        the result.
+ *
+ * @param[in]  s        The destination string to append to.
+ *
+ * @param[in]  a        The source string you want to append.
+ *
+ * @param[in]  n        The number of characters you want to append from the
+ *                      string.
+ *
+ * @return              The duplicated string, NULL on error.
+ *
+ * @see talloc_strndup()
+ */
 char *talloc_strndup_append(char *s, const char *a, size_t n);
+
+/**
+ * @brief Append at most n characters of a string to given buffer and duplicate
+ *        the result.
+ *
+ * @param[in]  s        The destination buffer to append to.
+ *
+ * @param[in]  a        The source string you want to append.
+ *
+ * @param[in]  n        The number of characters you want to append from the
+ *                      string.
+ *
+ * @return              The duplicated string, NULL on error.
+ *
+ * @see talloc_strndup()
+ */
 char *talloc_strndup_append_buffer(char *s, const char *a, size_t n);
 
 /**
@@ -1314,7 +1419,37 @@ char *talloc_strndup_append_buffer(char *s, const char *a, size_t n);
  * @return              The formatted string, NULL on error.
  */
 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
+
+/**
+ * @brief Format a string given a va_list and append it to the given destination
+ *        string.
+ *
+ * @param[in]  s        The destination string to append to.
+ *
+ * @param[in]  fmt      The format string.
+ *
+ * @param[in]  ap       The parameters used to fill fmt.
+ *
+ * @return              The formatted string, NULL on error.
+ *
+ * @see talloc_vasprintf()
+ */
 char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
+
+/**
+ * @brief Format a string given a va_list and append it to the given destination
+ *        buffer.
+ *
+ * @param[in]  s        The destination buffer to append to.
+ *
+ * @param[in]  fmt      The format string.
+ *
+ * @param[in]  ap       The parameters used to fill fmt.
+ *
+ * @return              The formatted string, NULL on error.
+ *
+ * @see talloc_vasprintf()
+ */
 char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
 
 /**
@@ -1343,7 +1478,7 @@ char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3)
  * @brief Append a formatted string to another string.
  *
  * This function appends the given formatted string to the given string. Use
- * this varient when the string in the current talloc buffer may have been
+ * this variant when the string in the current talloc buffer may have been
  * truncated in length.
  *
  * This functions sets the name of the new pointer to the new
@@ -1441,7 +1576,7 @@ void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f
  * @brief Print a summary report of all memory used by ptr.
  *
  * This provides a more detailed report than talloc_report(). It will
- * recursively print the ensire tree of memory referenced by the
+ * recursively print the entire tree of memory referenced by the
  * pointer. References in the tree are shown by giving the name of the
  * pointer that is referenced.
  *
@@ -1576,6 +1711,26 @@ void talloc_enable_leak_report(void);
  */
 void talloc_enable_leak_report_full(void);
 
+#define TALLOC_FLAG_WARN_MAY_REFERENCE 0x1
+/**
+ * @brief Set a global flag which alters talloc's behavior.
+ *
+ * 0 is returned if the flag is known, -1 otherwise.
+ *
+ * Flag is one of the following:
+ * TALLOC_FLAG_WARN_MAY_REFERENCE:
+ *     Warn if talloc_reference() is called on a pointer without talloc_may_reference()
+ *     being called first.
+ */
+int talloc_set_flag(unsigned int flag);
+
+/**
+ * @brief Remove a global flag which alters talloc's behavior.
+ *
+ * 0 is returned if the flag is known, -1 otherwise.
+ */
+int talloc_unset_flag(unsigned int flag);
+
 /* @} ******************************************************************/
 
 void talloc_set_abort_fn(void (*abort_fn)(const char *reason));
@@ -1591,4 +1746,12 @@ void talloc_set_log_stderr(void);
 #define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a))
 #endif
 
+#ifndef TALLOC_MAX_DEPTH
+#define TALLOC_MAX_DEPTH 10000
+#endif
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
 #endif