You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

364 lines
8.9 KiB

23 years ago
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Zend Engine |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1998-2003 Zend Technologies Ltd. (http://www.zend.com) |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 2.00 of the Zend license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available at through the world-wide-web at |
  10. | http://www.zend.com/license/2_00.txt. |
  11. | If you did not receive a copy of the Zend license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@zend.com so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Harald Radi <harald.radi@nme.at> |
  16. +----------------------------------------------------------------------+
  17. */
  18. /* $Id$ */
  19. #include "zend_ts_hash.h"
  20. /* ts management functions */
  21. static void begin_read(TsHashTable *ht)
  22. {
  23. #ifdef ZTS
  24. tsrm_mutex_lock(ht->mx_reader);
  25. if ((++(ht->reader)) == 1) {
  26. tsrm_mutex_lock(ht->mx_writer);
  27. }
  28. tsrm_mutex_unlock(ht->mx_reader);
  29. #endif
  30. }
  31. static void end_read(TsHashTable *ht)
  32. {
  33. #ifdef ZTS
  34. tsrm_mutex_lock(ht->mx_reader);
  35. if ((--(ht->reader)) == 0) {
  36. tsrm_mutex_unlock(ht->mx_writer);
  37. }
  38. tsrm_mutex_unlock(ht->mx_reader);
  39. #endif
  40. }
  41. static void begin_write(TsHashTable *ht)
  42. {
  43. #ifdef ZTS
  44. tsrm_mutex_lock(ht->mx_writer);
  45. #endif
  46. }
  47. static void end_write(TsHashTable *ht)
  48. {
  49. #ifdef ZTS
  50. tsrm_mutex_unlock(ht->mx_writer);
  51. #endif
  52. }
  53. /* delegates */
  54. ZEND_API int zend_ts_hash_init(TsHashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent)
  55. {
  56. #ifdef ZTS
  57. ht->mx_reader = tsrm_mutex_alloc();
  58. ht->mx_writer = tsrm_mutex_alloc();
  59. ht->reader = 0;
  60. #endif
  61. return zend_hash_init(TS_HASH(ht), nSize, pHashFunction, pDestructor, persistent);
  62. }
  63. ZEND_API int zend_ts_hash_init_ex(TsHashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection)
  64. {
  65. #ifdef ZTS
  66. ht->mx_reader = tsrm_mutex_alloc();
  67. ht->mx_writer = tsrm_mutex_alloc();
  68. ht->reader = 0;
  69. #endif
  70. return zend_hash_init_ex(TS_HASH(ht), nSize, pHashFunction, pDestructor, persistent, bApplyProtection);
  71. }
  72. ZEND_API void zend_ts_hash_destroy(TsHashTable *ht)
  73. {
  74. #ifdef ZTS
  75. tsrm_mutex_free(ht->mx_reader);
  76. tsrm_mutex_free(ht->mx_writer);
  77. #endif
  78. zend_hash_destroy(TS_HASH(ht));
  79. }
  80. ZEND_API void zend_ts_hash_clean(TsHashTable *ht)
  81. {
  82. ht->reader = 0;
  83. zend_hash_clean(TS_HASH(ht));
  84. }
  85. ZEND_API int zend_ts_hash_add_or_update(TsHashTable *ht, char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest, int flag)
  86. {
  87. int retval;
  88. begin_write(ht);
  89. retval = zend_hash_add_or_update(TS_HASH(ht), arKey, nKeyLength, pData, nDataSize, pDest, flag);
  90. end_write(ht);
  91. return retval;
  92. }
  93. ZEND_API int zend_ts_hash_quick_add_or_update(TsHashTable *ht, char *arKey, uint nKeyLength, ulong h, void *pData, uint nDataSize, void **pDest, int flag)
  94. {
  95. int retval;
  96. begin_write(ht);
  97. retval = zend_hash_quick_add_or_update(TS_HASH(ht), arKey, nKeyLength, h, pData, nDataSize, pDest, flag);
  98. end_write(ht);
  99. return retval;
  100. }
  101. ZEND_API int zend_ts_hash_index_update_or_next_insert(TsHashTable *ht, ulong h, void *pData, uint nDataSize, void **pDest, int flag)
  102. {
  103. int retval;
  104. begin_write(ht);
  105. retval = zend_hash_index_update_or_next_insert(TS_HASH(ht), h, pData, nDataSize, pDest, flag);
  106. end_write(ht);
  107. return retval;
  108. }
  109. ZEND_API int zend_ts_hash_add_empty_element(TsHashTable *ht, char *arKey, uint nKeyLength)
  110. {
  111. int retval;
  112. begin_write(ht);
  113. retval = zend_hash_add_empty_element(TS_HASH(ht), arKey, nKeyLength);
  114. end_write(ht);
  115. return retval;
  116. }
  117. ZEND_API void zend_ts_hash_graceful_destroy(TsHashTable *ht)
  118. {
  119. #ifdef ZTS
  120. tsrm_mutex_free(ht->mx_reader);
  121. tsrm_mutex_free(ht->mx_reader);
  122. #endif
  123. zend_hash_graceful_destroy(TS_HASH(ht));
  124. }
  125. ZEND_API void zend_ts_hash_apply(TsHashTable *ht, apply_func_t apply_func TSRMLS_DC)
  126. {
  127. begin_write(ht);
  128. zend_hash_apply(TS_HASH(ht), apply_func TSRMLS_CC);
  129. end_write(ht);
  130. }
  131. ZEND_API void zend_ts_hash_apply_with_argument(TsHashTable *ht, apply_func_arg_t apply_func, void *argument TSRMLS_DC)
  132. {
  133. begin_write(ht);
  134. zend_hash_apply_with_argument(TS_HASH(ht), apply_func, argument TSRMLS_CC);
  135. end_write(ht);
  136. }
  137. ZEND_API void zend_ts_hash_apply_with_arguments(TsHashTable *ht, apply_func_args_t apply_func, int num_args, ...)
  138. {
  139. va_list args;
  140. va_start(args, num_args);
  141. begin_write(ht);
  142. zend_hash_apply_with_arguments(TS_HASH(ht), apply_func, num_args, args);
  143. end_write(ht);
  144. va_end(args);
  145. }
  146. ZEND_API void zend_ts_hash_reverse_apply(TsHashTable *ht, apply_func_t apply_func TSRMLS_DC)
  147. {
  148. begin_write(ht);
  149. zend_hash_reverse_apply(TS_HASH(ht), apply_func TSRMLS_CC);
  150. end_write(ht);
  151. }
  152. ZEND_API int zend_ts_hash_del_key_or_index(TsHashTable *ht, char *arKey, uint nKeyLength, ulong h, int flag)
  153. {
  154. int retval;
  155. begin_write(ht);
  156. retval = zend_hash_del_key_or_index(TS_HASH(ht), arKey, nKeyLength, h, flag);
  157. end_write(ht);
  158. return retval;
  159. }
  160. ZEND_API ulong zend_ts_get_hash_value(TsHashTable *ht, char *arKey, uint nKeyLength)
  161. {
  162. ulong retval;
  163. begin_read(ht);
  164. retval = zend_get_hash_value(arKey, nKeyLength);
  165. end_read(ht);
  166. return retval;
  167. }
  168. ZEND_API int zend_ts_hash_find(TsHashTable *ht, char *arKey, uint nKeyLength, void **pData)
  169. {
  170. int retval;
  171. begin_read(ht);
  172. retval = zend_hash_find(TS_HASH(ht), arKey, nKeyLength, pData);
  173. end_read(ht);
  174. return retval;
  175. }
  176. ZEND_API int zend_ts_hash_quick_find(TsHashTable *ht, char *arKey, uint nKeyLength, ulong h, void **pData)
  177. {
  178. int retval;
  179. begin_read(ht);
  180. retval = zend_hash_quick_find(TS_HASH(ht), arKey, nKeyLength, h, pData);
  181. end_read(ht);
  182. return retval;
  183. }
  184. ZEND_API int zend_ts_hash_index_find(TsHashTable *ht, ulong h, void **pData)
  185. {
  186. int retval;
  187. begin_read(ht);
  188. retval = zend_hash_index_find(TS_HASH(ht), h, pData);
  189. end_read(ht);
  190. return retval;
  191. }
  192. ZEND_API int zend_ts_hash_exists(TsHashTable *ht, char *arKey, uint nKeyLength)
  193. {
  194. int retval;
  195. begin_read(ht);
  196. retval = zend_hash_exists(TS_HASH(ht), arKey, nKeyLength);
  197. end_read(ht);
  198. return retval;
  199. }
  200. ZEND_API int zend_ts_hash_index_exists(TsHashTable *ht, ulong h)
  201. {
  202. int retval;
  203. begin_read(ht);
  204. retval = zend_hash_index_exists(TS_HASH(ht), h);
  205. end_read(ht);
  206. return retval;
  207. }
  208. ZEND_API void zend_ts_hash_copy(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size)
  209. {
  210. begin_read(source);
  211. begin_write(target);
  212. zend_hash_copy(TS_HASH(target), TS_HASH(source), pCopyConstructor, tmp, size);
  213. end_write(target);
  214. end_read(source);
  215. }
  216. ZEND_API void zend_ts_hash_merge(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size, int overwrite)
  217. {
  218. begin_read(source);
  219. begin_write(target);
  220. zend_hash_merge(TS_HASH(target), TS_HASH(source), pCopyConstructor, tmp, size, overwrite);
  221. end_write(target);
  222. end_read(source);
  223. }
  224. ZEND_API void zend_ts_hash_merge_ex(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor, uint size, merge_checker_func_t pMergeSource, void *pParam)
  225. {
  226. begin_read(source);
  227. begin_write(target);
  228. zend_hash_merge_ex(TS_HASH(target), TS_HASH(source), pCopyConstructor, size, pMergeSource, pParam);
  229. end_write(target);
  230. end_read(source);
  231. }
  232. ZEND_API int zend_ts_hash_sort(TsHashTable *ht, sort_func_t sort_func, compare_func_t compare_func, int renumber TSRMLS_DC)
  233. {
  234. int retval;
  235. begin_write(ht);
  236. retval = zend_hash_sort(TS_HASH(ht), sort_func, compare_func, renumber TSRMLS_CC);
  237. end_write(ht);
  238. return retval;
  239. }
  240. ZEND_API int zend_ts_hash_compare(TsHashTable *ht1, TsHashTable *ht2, compare_func_t compar, zend_bool ordered TSRMLS_DC)
  241. {
  242. int retval;
  243. begin_read(ht1);
  244. begin_read(ht2);
  245. retval = zend_hash_compare(TS_HASH(ht1), TS_HASH(ht2), compar, ordered TSRMLS_CC);
  246. end_read(ht2);
  247. end_read(ht1);
  248. return retval;
  249. }
  250. ZEND_API int zend_ts_hash_minmax(TsHashTable *ht, compare_func_t compar, int flag, void **pData TSRMLS_DC)
  251. {
  252. int retval;
  253. begin_read(ht);
  254. retval = zend_hash_minmax(TS_HASH(ht), compar, flag, pData TSRMLS_CC);
  255. end_read(ht);
  256. return retval;
  257. }
  258. ZEND_API int zend_ts_hash_num_elements(TsHashTable *ht)
  259. {
  260. int retval;
  261. begin_read(ht);
  262. retval = zend_hash_num_elements(TS_HASH(ht));
  263. end_read(ht);
  264. return retval;
  265. }
  266. ZEND_API int zend_ts_hash_rehash(TsHashTable *ht)
  267. {
  268. int retval;
  269. begin_write(ht);
  270. retval = zend_hash_rehash(TS_HASH(ht));
  271. end_write(ht);
  272. return retval;
  273. }
  274. #if ZEND_DEBUG
  275. void zend_ts_hash_display_pListTail(TsHashTable *ht)
  276. {
  277. begin_read(ht);
  278. zend_hash_display_pListTail(TS_HASH(ht));
  279. end_read(ht);
  280. }
  281. void zend_ts_hash_display(TsHashTable *ht)
  282. {
  283. begin_read(ht);
  284. zend_hash_display(TS_HASH(ht));
  285. end_read(ht);
  286. }
  287. #endif
  288. /*
  289. * Local variables:
  290. * tab-width: 4
  291. * c-basic-offset: 4
  292. * indent-tabs-mode: t
  293. * End:
  294. */