take.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /* CC0 (Public domain) - see LICENSE file for details */
  2. #ifndef CCAN_TAKE_H
  3. #define CCAN_TAKE_H
  4. #include "config.h"
  5. #include <stdbool.h>
  6. /**
  7. * take - record a pointer to be consumed by the function its handed to.
  8. * @p: the pointer to mark, or NULL.
  9. *
  10. * This marks a pointer object to be freed by the called function,
  11. * which is extremely useful for chaining functions. It works on
  12. * NULL, for pass-through error handling.
  13. */
  14. #define take(p) (take_typeof(p) take_((p)))
  15. /**
  16. * taken - check (and un-take) a pointer was passed with take()
  17. * @p: the pointer to check.
  18. *
  19. * A function which accepts take() arguments uses this to see if it
  20. * should own the pointer; it will be removed from the take list, so
  21. * this only returns true once.
  22. *
  23. * Example:
  24. * // Silly routine to add 1
  25. * static int *add_one(const int *num)
  26. * {
  27. * int *ret;
  28. * if (taken(num))
  29. * ret = (int *)num;
  30. * else
  31. * ret = malloc(sizeof(int));
  32. * if (ret)
  33. * *ret = (*num) + 1;
  34. * return ret;
  35. * }
  36. */
  37. bool taken(const void *p);
  38. /**
  39. * is_taken - check if a pointer was passed with take()
  40. * @p: the pointer to check.
  41. *
  42. * This is like the above, but doesn't remove it from the taken list.
  43. *
  44. * Example:
  45. * // Silly routine to add 1: doesn't handle taken args!
  46. * static int *add_one_notake(const int *num)
  47. * {
  48. * int *ret = malloc(sizeof(int));
  49. * assert(!is_taken(num));
  50. * if (ret)
  51. * *ret = (*num) + 1;
  52. * return ret;
  53. * }
  54. */
  55. bool is_taken(const void *p);
  56. /**
  57. * taken_any - are there any taken pointers?
  58. *
  59. * Mainly useful for debugging take() leaks.
  60. *
  61. * Example:
  62. * static void cleanup(void)
  63. * {
  64. * assert(!taken_any());
  65. * }
  66. */
  67. bool taken_any(void);
  68. /**
  69. * take_cleanup - remove all taken pointers from list.
  70. *
  71. * This is useful in atexit() handlers for valgrind-style leak detection.
  72. *
  73. * Example:
  74. * static void cleanup2(void)
  75. * {
  76. * take_cleanup();
  77. * }
  78. */
  79. void take_cleanup(void);
  80. /**
  81. * take_allocfail - set function to call if we can't reallocated taken array.
  82. * @fn: the function.
  83. *
  84. * If this is not set, then if the array reallocation fails, the
  85. * pointer won't be marked taken(). If @fn returns, it is expected to
  86. * free the pointer; we return NULL from take() and the function handles
  87. * it like any allocation failure.
  88. *
  89. * Example:
  90. * static void free_on_fail(const void *p)
  91. * {
  92. * free((void *)p);
  93. * }
  94. *
  95. * static void init(void)
  96. * {
  97. * take_allocfail(free_on_fail);
  98. * }
  99. */
  100. void take_allocfail(void (*fn)(const void *p));
  101. /* Private functions */
  102. #if HAVE_TYPEOF
  103. #define take_typeof(ptr) (__typeof__(ptr))
  104. #else
  105. #define take_typeof(ptr)
  106. #endif
  107. void *take_(const void *p);
  108. #endif /* CCAN_TAKE_H */