repl5_replica_hash.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. *
  6. * License: GPL (version 3 or any later version).
  7. * See LICENSE for details.
  8. * END COPYRIGHT BLOCK **/
  9. #ifdef HAVE_CONFIG_H
  10. # include <config.h>
  11. #endif
  12. /* repl5_replica_hash.c */
  13. #include "repl5.h"
  14. #include "plhash.h"
  15. /* global data */
  16. static PLHashTable *s_hash;
  17. static Slapi_RWLock *s_lock;
  18. struct repl_enum_data
  19. {
  20. FNEnumReplica fn;
  21. void *arg;
  22. };
  23. /* Forward declarations */
  24. static PRIntn replica_destroy_hash_entry (PLHashEntry *he, PRIntn index, void *arg);
  25. static PRIntn replica_enumerate (PLHashEntry *he, PRIntn index, void *hash_data);
  26. int replica_init_name_hash ()
  27. {
  28. /* allocate table */
  29. s_hash = PL_NewHashTable(0, PL_HashString, PL_CompareStrings,
  30. PL_CompareValues, NULL, NULL);
  31. if (s_hash == NULL)
  32. {
  33. slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_init_name_hash: "
  34. "failed to allocate hash table; NSPR error - %d\n",
  35. PR_GetError ());
  36. return -1;
  37. }
  38. /* create lock */
  39. s_lock = slapi_new_rwlock();
  40. if (s_lock == NULL)
  41. {
  42. slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_init_name_hash: "
  43. "failed to create lock; NSPR error - %d\n",
  44. PR_GetError ());
  45. replica_destroy_name_hash ();
  46. return -1;
  47. }
  48. return 0;
  49. }
  50. void replica_destroy_name_hash ()
  51. {
  52. /* destroy the content */
  53. PL_HashTableEnumerateEntries(s_hash, replica_destroy_hash_entry, NULL);
  54. if (s_hash)
  55. PL_HashTableDestroy(s_hash);
  56. if (s_lock)
  57. slapi_destroy_rwlock (s_lock);
  58. }
  59. int replica_add_by_name (const char *name, Object *replica)
  60. {
  61. if (name == NULL || replica == NULL)
  62. {
  63. slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_add_by_name: NULL argument\n");
  64. return -1;
  65. }
  66. if (s_hash == NULL || s_lock == NULL)
  67. {
  68. slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_add_by_name: "
  69. "replica hash is not initialized\n");
  70. return -1;
  71. }
  72. slapi_rwlock_wrlock (s_lock);
  73. /* make sure that the name is unique */
  74. if (PL_HashTableLookup(s_hash, name) != NULL)
  75. {
  76. slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_add_by_name: "
  77. "replica with name (%s) already in the hash\n", name);
  78. slapi_rwlock_unlock (s_lock);
  79. return -1 ;
  80. }
  81. /* acquire replica object */
  82. object_acquire (replica);
  83. /* add replica */
  84. if (PL_HashTableAdd(s_hash, name, replica) == NULL)
  85. {
  86. slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_add_by_name: "
  87. "failed to add replica with name (%s); NSPR error - %d\n",
  88. name, PR_GetError ());
  89. object_release (replica);
  90. slapi_rwlock_unlock (s_lock);
  91. return -1;
  92. }
  93. slapi_rwlock_unlock (s_lock);
  94. return 0;
  95. }
  96. int replica_delete_by_name (const char *name)
  97. {
  98. Object *replica;
  99. if (name == NULL)
  100. {
  101. slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_delete_by_name: "
  102. "NULL argument\n");
  103. return -1;
  104. }
  105. if (s_hash == NULL || s_lock == NULL)
  106. {
  107. slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_delete_by_name: "
  108. "replica hash is not initialized\n");
  109. return -1;
  110. }
  111. slapi_rwlock_wrlock (s_lock);
  112. /* locate object */
  113. replica = (Object*)PL_HashTableLookup(s_hash, name);
  114. if (replica == NULL)
  115. {
  116. slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_delete_by_name: "
  117. "replica with name (%s) is not in the hash.\n", name);
  118. slapi_rwlock_unlock (s_lock);
  119. return -1;
  120. }
  121. /* remove from hash */
  122. PL_HashTableRemove(s_hash, name);
  123. /* release replica */
  124. object_release (replica);
  125. slapi_rwlock_unlock (s_lock);
  126. return 0;
  127. }
  128. Object* replica_get_by_name (const char *name)
  129. {
  130. Object *replica;
  131. if (name == NULL)
  132. {
  133. slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_get_by_name: "
  134. "NULL argument\n");
  135. return NULL;
  136. }
  137. if (s_hash == NULL || s_lock == NULL)
  138. {
  139. slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_get_by_name: "
  140. "replica hash is not initialized\n");
  141. return NULL;
  142. }
  143. slapi_rwlock_rdlock (s_lock);
  144. /* locate object */
  145. replica = (Object*)PL_HashTableLookup(s_hash, name);
  146. if (replica == NULL)
  147. {
  148. slapi_rwlock_unlock (s_lock);
  149. return NULL;
  150. }
  151. object_acquire (replica);
  152. slapi_rwlock_unlock (s_lock);
  153. return replica;
  154. }
  155. void replica_enumerate_replicas (FNEnumReplica fn, void *arg)
  156. {
  157. struct repl_enum_data data;
  158. PR_ASSERT (fn);
  159. data.fn = fn;
  160. data.arg = arg;
  161. slapi_rwlock_wrlock (s_lock);
  162. PL_HashTableEnumerateEntries(s_hash, replica_enumerate, &data);
  163. slapi_rwlock_unlock (s_lock);
  164. }
  165. /* Helper functions */
  166. /* this function called for each hash node during hash destruction */
  167. static PRIntn replica_destroy_hash_entry (PLHashEntry *he, PRIntn index, void *arg)
  168. {
  169. Object *r_obj;
  170. Replica *r;
  171. if (he == NULL)
  172. return HT_ENUMERATE_NEXT;
  173. r_obj = (Object*)he->value;
  174. r = (Replica*)object_get_data (r_obj);
  175. PR_ASSERT (r);
  176. /* flash replica state to the disk */
  177. replica_flush (r);
  178. /* release replica object */
  179. object_release (r_obj);
  180. return HT_ENUMERATE_REMOVE;
  181. }
  182. static PRIntn replica_enumerate (PLHashEntry *he, PRIntn index, void *hash_data)
  183. {
  184. Object *r_obj;
  185. Replica *r;
  186. struct repl_enum_data *data = hash_data;
  187. r_obj = (Object*)he->value;
  188. PR_ASSERT (r_obj);
  189. object_acquire (r_obj);
  190. r = (Replica*)object_get_data (r_obj);
  191. PR_ASSERT (r);
  192. data->fn (r, data->arg);
  193. object_release (r_obj);
  194. return HT_ENUMERATE_NEXT;
  195. }