posix_partition.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. * posix_partition.c
  3. */
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <assert.h>
  7. #include <string.h>
  8. #include "private.h"
  9. extern void sysheap_suppress_leak_detection(void);
  10. extern void sysheap_restore_leak_detection(void);
  11. typedef struct _key_data key_data_t;
  12. struct _key_data {
  13. lub_partition_t *partition;
  14. lub_heap_t *local_heap;
  15. };
  16. /*-------------------------------------------------------- */
  17. static void lub_posix_partition_destroy_key(void *arg)
  18. {
  19. key_data_t *key_data = arg;
  20. lub_partition_destroy_local_heap(key_data->partition,
  21. key_data->local_heap);
  22. lub_partition_global_realloc(key_data->partition, (char **)key_data, 0,
  23. LUB_HEAP_ALIGN_NATIVE);
  24. }
  25. /*-------------------------------------------------------- */
  26. lub_partition_t *lub_partition_create(const lub_partition_spec_t * spec)
  27. {
  28. lub_posix_partition_t *this;
  29. lub_partition_sysalloc_fn *alloc_fn = spec->sysalloc;
  30. if (!alloc_fn) {
  31. alloc_fn = malloc;
  32. }
  33. this = alloc_fn(sizeof(lub_posix_partition_t));
  34. if (this) {
  35. lub_posix_partition_init(this, spec);
  36. }
  37. return &this->m_base;
  38. }
  39. /*-------------------------------------------------------- */
  40. void
  41. lub_posix_partition_init(lub_posix_partition_t * this,
  42. const lub_partition_spec_t * spec)
  43. {
  44. memset(this, sizeof(*this), 0);
  45. /* initialise the base class */
  46. lub_partition_init(&this->m_base, spec);
  47. /* initialise the global mutex */
  48. if (0 != pthread_mutex_init(&this->m_mutex, 0)) {
  49. perror("pthread_mutex_init() failed!");
  50. }
  51. /* initialise the local key */
  52. if (0 != pthread_key_create(&this->m_key,
  53. lub_posix_partition_destroy_key)) {
  54. perror("pthread_key_create() failed!");
  55. }
  56. }
  57. /*-------------------------------------------------------- */
  58. void lub_partition_destroy(lub_partition_t * instance)
  59. {
  60. lub_posix_partition_t *this = (void *)instance;
  61. /* finalise the base class */
  62. lub_partition_fini(&this->m_base);
  63. /* now clean up the global mutex */
  64. if (0 != pthread_mutex_destroy(&this->m_mutex)) {
  65. perror("pthread_mutex_destroy() failed!");
  66. }
  67. /* now clean up the local key */
  68. if (0 != pthread_key_delete(this->m_key)) {
  69. perror("pthread_key_delete() failed!");
  70. }
  71. free(this);
  72. }
  73. /*-------------------------------------------------------- */
  74. lub_heap_t *lub_partition__get_local_heap(lub_partition_t * instance)
  75. {
  76. lub_heap_t *result = 0;
  77. lub_posix_partition_t *this = (void *)instance;
  78. key_data_t *key_data = pthread_getspecific(this->m_key);
  79. if (key_data) {
  80. result = key_data->local_heap;
  81. }
  82. return result;
  83. }
  84. /*-------------------------------------------------------- */
  85. void
  86. lub_partition__set_local_heap(lub_partition_t * instance, lub_heap_t * heap)
  87. {
  88. lub_posix_partition_t *this = (void *)instance;
  89. key_data_t *key_data = 0;
  90. #if defined(__CYGWIN__)
  91. /* cygwin seems to leak key_data!!! so we ignore this for the time being... */
  92. lub_heap_leak_suppress_detection(instance->m_global_heap);
  93. #endif /* __CYGWIN__ */
  94. lub_partition_global_realloc(instance, (char **)&key_data,
  95. sizeof(key_data_t), LUB_HEAP_ALIGN_NATIVE);
  96. #if defined(__CYGWIN__)
  97. /* cygwin seems to leak key_data!!! so we ignore this for the time being... */
  98. lub_heap_leak_restore_detection(instance->m_global_heap);
  99. #endif /* __CYGWIN__ */
  100. assert(key_data);
  101. key_data->partition = instance;
  102. key_data->local_heap = heap;
  103. if (0 != pthread_getspecific(this->m_key)) {
  104. assert(NULL == "Local heap already exists!");
  105. }
  106. if (0 != pthread_setspecific(this->m_key, key_data)) {
  107. perror("pthread_setspecific() failed!");
  108. }
  109. }
  110. /*-------------------------------------------------------- */
  111. void lub_partition_lock(lub_partition_t * instance)
  112. {
  113. lub_posix_partition_t *this = (void *)instance;
  114. if (0 != pthread_mutex_lock(&this->m_mutex)) {
  115. perror("pthread_mutex_lock() failed!");
  116. }
  117. }
  118. /*-------------------------------------------------------- */
  119. void lub_partition_unlock(lub_partition_t * instance)
  120. {
  121. lub_posix_partition_t *this = (void *)instance;
  122. if (0 != pthread_mutex_unlock(&this->m_mutex)) {
  123. perror("pthread_mutex_unlock() failed!");
  124. }
  125. }
  126. /*-------------------------------------------------------- */