grefcount.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /* grefcount.h: Reference counting
  2. *
  3. * Copyright 2018 Emmanuele Bassi
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2.1 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #ifndef __GREFCOUNT_H__
  19. #define __GREFCOUNT_H__
  20. #if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
  21. #error "Only <glib.h> can be included directly."
  22. #endif
  23. #include <glib/gatomic.h>
  24. #include <glib/gtypes.h>
  25. G_BEGIN_DECLS
  26. GLIB_AVAILABLE_IN_2_58
  27. void g_ref_count_init (grefcount *rc);
  28. GLIB_AVAILABLE_IN_2_58
  29. void g_ref_count_inc (grefcount *rc);
  30. GLIB_AVAILABLE_IN_2_58
  31. gboolean g_ref_count_dec (grefcount *rc);
  32. GLIB_AVAILABLE_IN_2_58
  33. gboolean g_ref_count_compare (grefcount *rc,
  34. gint val);
  35. GLIB_AVAILABLE_IN_2_58
  36. void g_atomic_ref_count_init (gatomicrefcount *arc);
  37. GLIB_AVAILABLE_IN_2_58
  38. void g_atomic_ref_count_inc (gatomicrefcount *arc);
  39. GLIB_AVAILABLE_IN_2_58
  40. gboolean g_atomic_ref_count_dec (gatomicrefcount *arc);
  41. GLIB_AVAILABLE_IN_2_58
  42. gboolean g_atomic_ref_count_compare (gatomicrefcount *arc,
  43. gint val);
  44. /* On GCC we can use __extension__ to inline the API without using
  45. * ancillary functions; we only do this when disabling checks, as
  46. * it disables warnings when saturating the reference counters
  47. */
  48. #if defined(__GNUC__) && defined(G_DISABLE_CHECKS)
  49. # define g_ref_count_init(rc) \
  50. (G_GNUC_EXTENSION ({ \
  51. G_STATIC_ASSERT (sizeof *(rc) == sizeof (grefcount)); \
  52. (void) (0 ? *(rc) ^ *(rc) : 1); \
  53. *(rc) = -1; \
  54. }))
  55. # define g_ref_count_inc(rc) \
  56. (G_GNUC_EXTENSION ({ \
  57. G_STATIC_ASSERT (sizeof *(rc) == sizeof (grefcount)); \
  58. (void) (0 ? *(rc) ^ *(rc) : 1); \
  59. if (*(rc) == G_MININT) ; else { \
  60. *(rc) -= 1; \
  61. } \
  62. }))
  63. # define g_ref_count_dec(rc) \
  64. (G_GNUC_EXTENSION ({ \
  65. G_STATIC_ASSERT (sizeof *(rc) == sizeof (grefcount)); \
  66. grefcount __rc = *(rc); \
  67. __rc += 1; \
  68. if (__rc == 0) ; else { \
  69. *(rc) = __rc; \
  70. } \
  71. (gboolean) (__rc == 0); \
  72. }))
  73. # define g_ref_count_compare(rc,val) \
  74. (G_GNUC_EXTENSION ({ \
  75. G_STATIC_ASSERT (sizeof *(rc) == sizeof (grefcount)); \
  76. (void) (0 ? *(rc) ^ (val) : 1); \
  77. (gboolean) (*(rc) == -(val)); \
  78. }))
  79. # define g_atomic_ref_count_init(rc) \
  80. (G_GNUC_EXTENSION ({ \
  81. G_STATIC_ASSERT (sizeof *(rc) == sizeof (gatomicrefcount)); \
  82. (void) (0 ? *(rc) ^ *(rc) : 1); \
  83. *(rc) = 1; \
  84. }))
  85. # define g_atomic_ref_count_inc(rc) \
  86. (G_GNUC_EXTENSION ({ \
  87. G_STATIC_ASSERT (sizeof *(rc) == sizeof (gatomicrefcount)); \
  88. (void) (0 ? *(rc) ^ *(rc) : 1); \
  89. (void) (g_atomic_int_get (rc) == G_MAXINT ? 0 : g_atomic_int_inc ((rc))); \
  90. }))
  91. # define g_atomic_ref_count_dec(rc) \
  92. (G_GNUC_EXTENSION ({ \
  93. G_STATIC_ASSERT (sizeof *(rc) == sizeof (gatomicrefcount)); \
  94. (void) (0 ? *(rc) ^ *(rc) : 1); \
  95. g_atomic_int_dec_and_test ((rc)); \
  96. }))
  97. # define g_atomic_ref_count_compare(rc,val) \
  98. (G_GNUC_EXTENSION ({ \
  99. G_STATIC_ASSERT (sizeof *(rc) == sizeof (gatomicrefcount)); \
  100. (void) (0 ? *(rc) ^ (val) : 1); \
  101. (gboolean) (g_atomic_int_get (rc) == (val)); \
  102. }))
  103. #endif /* __GNUC__ && G_DISABLE_CHECKS */
  104. G_END_DECLS
  105. #endif /* __GREFCOUNT_H__ */