object.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * lib/object.c Generic Cacheable Object
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation version 2.1
  7. * of the License.
  8. *
  9. * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  10. */
  11. /**
  12. * @ingroup cache
  13. * @defgroup object Object
  14. * @{
  15. */
  16. #include <netlink-local.h>
  17. #include <netlink/netlink.h>
  18. #include <netlink/cache.h>
  19. #include <netlink/object.h>
  20. #include <netlink/utils.h>
  21. static inline struct nl_object_ops *obj_ops(struct nl_object *obj)
  22. {
  23. if (!obj->ce_ops)
  24. BUG();
  25. return obj->ce_ops;
  26. }
  27. /**
  28. * @name Object Creation/Deletion
  29. * @{
  30. */
  31. /**
  32. * Allocate a new object of kind specified by the operations handle
  33. * @arg ops cache operations handle
  34. * @return The new object or NULL
  35. */
  36. struct nl_object *nl_object_alloc(struct nl_object_ops *ops)
  37. {
  38. struct nl_object *new;
  39. if (ops->oo_size < sizeof(*new))
  40. BUG();
  41. new = calloc(1, ops->oo_size);
  42. if (!new)
  43. return NULL;
  44. new->ce_refcnt = 1;
  45. nl_init_list_head(&new->ce_list);
  46. new->ce_ops = ops;
  47. if (ops->oo_constructor)
  48. ops->oo_constructor(new);
  49. NL_DBG(4, "Allocated new object %p\n", new);
  50. return new;
  51. }
  52. struct nl_derived_object {
  53. NLHDR_COMMON
  54. char data;
  55. };
  56. /**
  57. * Allocate a new object and copy all data from an existing object
  58. * @arg obj object to inherite data from
  59. * @return The new object or NULL.
  60. */
  61. struct nl_object *nl_object_clone(struct nl_object *obj)
  62. {
  63. struct nl_object *new;
  64. struct nl_object_ops *ops = obj_ops(obj);
  65. int doff = offsetof(struct nl_derived_object, data);
  66. int size;
  67. new = nl_object_alloc(ops);
  68. if (!new)
  69. return NULL;
  70. size = ops->oo_size - doff;
  71. if (size < 0)
  72. BUG();
  73. new->ce_ops = obj->ce_ops;
  74. new->ce_msgtype = obj->ce_msgtype;
  75. if (size)
  76. memcpy((void *)new + doff, (void *)obj + doff, size);
  77. if (ops->oo_clone) {
  78. if (ops->oo_clone(new, obj) < 0) {
  79. nl_object_free(new);
  80. return NULL;
  81. }
  82. } else if (size && ops->oo_free_data)
  83. BUG();
  84. return new;
  85. }
  86. /**
  87. * Free a cacheable object
  88. * @arg obj object to free
  89. *
  90. * @return 0 or a negative error code.
  91. */
  92. void nl_object_free(struct nl_object *obj)
  93. {
  94. struct nl_object_ops *ops = obj_ops(obj);
  95. if (obj->ce_refcnt > 0)
  96. NL_DBG(1, "Warning: Freeing object in use...\n");
  97. if (obj->ce_cache)
  98. nl_cache_remove(obj);
  99. if (ops->oo_free_data)
  100. ops->oo_free_data(obj);
  101. free(obj);
  102. NL_DBG(4, "Freed object %p\n", obj);
  103. }
  104. /** @} */
  105. /**
  106. * @name Reference Management
  107. * @{
  108. */
  109. /** @} */
  110. /**
  111. * @name Utillities
  112. * @{
  113. */
  114. /** @} */
  115. /** @} */