refcnt.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #ifndef REF_COUNT_H
  2. #define REF_COUNT_H
  3. #pragma once
  4. #include <winpr/wtypes.h>
  5. #include <winpr/interlocked.h> /*for warning: implicit declaration of function InterlockedIncrement*/
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. #define __REF_COUNT_NOTHING
  10. #define __REF_COUNT_STATIC static
  11. typedef void (*refcnt_on_destroy)(void *inst);
  12. /*declare function prototype*/
  13. #define __DECLARE_REF_COUNT(typeprefix, type, modifier) \
  14. modifier int typeprefix##_inc_ref(type*); \
  15. modifier int typeprefix##_dec_ref(type*); \
  16. modifier int typeprefix##_ref_cnt(type*);
  17. #define DECLARE_REF_COUNT(typeprefix, type) __DECLARE_REF_COUNT(typeprefix, type, __REF_COUNT_NOTHING)
  18. #define DECLARE_REF_COUNT_STATIC(typeprefix, type) __DECLARE_REF_COUNT(typeprefix, type, __REF_COUNT_STATIC)
  19. #define DECLARE_REF_COUNT_MEMBER(member) int member
  20. #define REF_COUNT_INIT(ep) *(ep) = 1
  21. /*
  22. *typeprefix: function prefix declare
  23. *type: the object type to deal with
  24. *member: object's member name in refcnt type
  25. *free_fn: the free function to free the object pointer
  26. *modifer: static or not(empty)
  27. */
  28. #define __IMPLEMENT_REF_COUNT(typeprefix, type, member, free_fn, modifer) \
  29. modifer int typeprefix##_inc_ref(type *o) { \
  30. return ++((o)->member); \
  31. }\
  32. modifer int typeprefix##_dec_ref(type *o) { \
  33. if(--((o)->member) == 0) \
  34. free_fn(o); \
  35. return (o)->member; \
  36. }\
  37. modifer int typeprefix##_ref_cnt(type* o) { \
  38. return (o)->member; \
  39. }
  40. #define IMPLEMENT_REF_COUNT(typeprefix, type, member, free_fn) __IMPLEMENT_REF_COUNT(typeprefix, type, member, free_fn, __REF_COUNT_NOTHING)
  41. #define IMPLEMENT_REF_COUNT_STATIC(typeprefix, type, member, free_fn) __IMPLEMENT_REF_COUNT(typeprefix, type, member, free_fn, __REF_COUNT_STATIC)
  42. /*in case: multi thread environment*/
  43. #define __IMPLEMENT_REF_COUNT_MT(typeprefix, type, member, free_fn, modifier) \
  44. modifier int typeprefix##_inc_ref(type *o) {\
  45. return (int)InterlockedIncrement((LONG*)&((o)->member));\
  46. }\
  47. modifier int typeprefix##_dec_ref(type *o) { \
  48. int ret = InterlockedDecrement((LONG*)&(o)->member); \
  49. if (0 == ret) \
  50. free_fn(o); \
  51. return ret; \
  52. }\
  53. modifier int typeprefix##_ref_cnt(type* o) { \
  54. return (o)->member; \
  55. }
  56. #define IMPLEMENT_REF_COUNT_MT(typeprefix, type, member, free_fn) __IMPLEMENT_REF_COUNT_MT(typeprefix, type, member, free_fn, __REF_COUNT_NOTHING)
  57. #define IMPLEMENT_REF_COUNT_MT_STATIC(typeprefix, type, member, free_fn) __IMPLEMENT_REF_COUNT_MT(typeprefix, type, member, free_fn, __REF_COUNT_STATIC)
  58. #define inc_ref(type, ptr) type##_inc_ref(ptr)
  59. #define dec_ref(type, ptr) type##_dec_ref(ptr)
  60. #define ref_cnt(type, ptr) type##_ref_cnt(ptr)
  61. #ifdef __cplusplus
  62. } // extern "C" {
  63. #endif
  64. #endif // REF_COUNT_H