1 /*
2 +----------------------------------------------------------------------+
3 | Zend Engine |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1998-2018 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 through the world-wide-web at the following url: |
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
19 #include "zend.h"
20 #include "zend_ts_hash.h"
21
22 /* ts management functions */
begin_read(TsHashTable * ht)23 static void begin_read(TsHashTable *ht)
24 {
25 #ifdef ZTS
26 tsrm_mutex_lock(ht->mx_reader);
27 if ((++(ht->reader)) == 1) {
28 tsrm_mutex_lock(ht->mx_writer);
29 }
30 tsrm_mutex_unlock(ht->mx_reader);
31 #endif
32 }
33
end_read(TsHashTable * ht)34 static void end_read(TsHashTable *ht)
35 {
36 #ifdef ZTS
37 tsrm_mutex_lock(ht->mx_reader);
38 if ((--(ht->reader)) == 0) {
39 tsrm_mutex_unlock(ht->mx_writer);
40 }
41 tsrm_mutex_unlock(ht->mx_reader);
42 #endif
43 }
44
begin_write(TsHashTable * ht)45 static void begin_write(TsHashTable *ht)
46 {
47 #ifdef ZTS
48 tsrm_mutex_lock(ht->mx_writer);
49 #endif
50 }
51
end_write(TsHashTable * ht)52 static void end_write(TsHashTable *ht)
53 {
54 #ifdef ZTS
55 tsrm_mutex_unlock(ht->mx_writer);
56 #endif
57 }
58
59 /* delegates */
_zend_ts_hash_init(TsHashTable * ht,uint32_t nSize,dtor_func_t pDestructor,zend_bool persistent)60 ZEND_API void _zend_ts_hash_init(TsHashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent)
61 {
62 #ifdef ZTS
63 ht->mx_reader = tsrm_mutex_alloc();
64 ht->mx_writer = tsrm_mutex_alloc();
65 ht->reader = 0;
66 #endif
67 _zend_hash_init(TS_HASH(ht), nSize, pDestructor, persistent);
68 }
69
zend_ts_hash_destroy(TsHashTable * ht)70 ZEND_API void zend_ts_hash_destroy(TsHashTable *ht)
71 {
72 begin_write(ht);
73 zend_hash_destroy(TS_HASH(ht));
74 end_write(ht);
75
76 #ifdef ZTS
77 tsrm_mutex_free(ht->mx_reader);
78 tsrm_mutex_free(ht->mx_writer);
79 #endif
80 }
81
zend_ts_hash_clean(TsHashTable * ht)82 ZEND_API void zend_ts_hash_clean(TsHashTable *ht)
83 {
84 ht->reader = 0;
85 begin_write(ht);
86 zend_hash_clean(TS_HASH(ht));
87 end_write(ht);
88 }
89
zend_ts_hash_add(TsHashTable * ht,zend_string * key,zval * pData)90 ZEND_API zval *zend_ts_hash_add(TsHashTable *ht, zend_string *key, zval *pData)
91 {
92 zval *retval;
93
94 begin_write(ht);
95 retval = zend_hash_add(TS_HASH(ht), key, pData);
96 end_write(ht);
97
98 return retval;
99 }
100
zend_ts_hash_update(TsHashTable * ht,zend_string * key,zval * pData)101 ZEND_API zval *zend_ts_hash_update(TsHashTable *ht, zend_string *key, zval *pData)
102 {
103 zval *retval;
104
105 begin_write(ht);
106 retval = zend_hash_update(TS_HASH(ht), key, pData);
107 end_write(ht);
108
109 return retval;
110 }
111
zend_ts_hash_next_index_insert(TsHashTable * ht,zval * pData)112 ZEND_API zval *zend_ts_hash_next_index_insert(TsHashTable *ht, zval *pData)
113 {
114 zval *retval;
115
116 begin_write(ht);
117 retval = zend_hash_next_index_insert(TS_HASH(ht), pData);
118 end_write(ht);
119
120 return retval;
121 }
122
zend_ts_hash_index_update(TsHashTable * ht,zend_ulong h,zval * pData)123 ZEND_API zval *zend_ts_hash_index_update(TsHashTable *ht, zend_ulong h, zval *pData)
124 {
125 zval *retval;
126
127 begin_write(ht);
128 retval = zend_hash_index_update(TS_HASH(ht), h, pData);
129 end_write(ht);
130
131 return retval;
132 }
133
zend_ts_hash_add_empty_element(TsHashTable * ht,zend_string * key)134 ZEND_API zval *zend_ts_hash_add_empty_element(TsHashTable *ht, zend_string *key)
135 {
136 zval *retval;
137
138 begin_write(ht);
139 retval = zend_hash_add_empty_element(TS_HASH(ht), key);
140 end_write(ht);
141
142 return retval;
143 }
144
zend_ts_hash_graceful_destroy(TsHashTable * ht)145 ZEND_API void zend_ts_hash_graceful_destroy(TsHashTable *ht)
146 {
147 begin_write(ht);
148 zend_hash_graceful_destroy(TS_HASH(ht));
149 end_write(ht);
150
151 #ifdef ZTS
152 tsrm_mutex_free(ht->mx_reader);
153 tsrm_mutex_free(ht->mx_writer);
154 #endif
155 }
156
zend_ts_hash_apply(TsHashTable * ht,apply_func_t apply_func)157 ZEND_API void zend_ts_hash_apply(TsHashTable *ht, apply_func_t apply_func)
158 {
159 begin_write(ht);
160 zend_hash_apply(TS_HASH(ht), apply_func);
161 end_write(ht);
162 }
163
zend_ts_hash_apply_with_argument(TsHashTable * ht,apply_func_arg_t apply_func,void * argument)164 ZEND_API void zend_ts_hash_apply_with_argument(TsHashTable *ht, apply_func_arg_t apply_func, void *argument)
165 {
166 begin_write(ht);
167 zend_hash_apply_with_argument(TS_HASH(ht), apply_func, argument);
168 end_write(ht);
169 }
170
zend_ts_hash_apply_with_arguments(TsHashTable * ht,apply_func_args_t apply_func,int num_args,...)171 ZEND_API void zend_ts_hash_apply_with_arguments(TsHashTable *ht, apply_func_args_t apply_func, int num_args, ...)
172 {
173 va_list args;
174
175 va_start(args, num_args);
176 begin_write(ht);
177 zend_hash_apply_with_arguments(TS_HASH(ht), apply_func, num_args, args);
178 end_write(ht);
179 va_end(args);
180 }
181
zend_ts_hash_reverse_apply(TsHashTable * ht,apply_func_t apply_func)182 ZEND_API void zend_ts_hash_reverse_apply(TsHashTable *ht, apply_func_t apply_func)
183 {
184 begin_write(ht);
185 zend_hash_reverse_apply(TS_HASH(ht), apply_func);
186 end_write(ht);
187 }
188
zend_ts_hash_del(TsHashTable * ht,zend_string * key)189 ZEND_API int zend_ts_hash_del(TsHashTable *ht, zend_string *key)
190 {
191 int retval;
192
193 begin_write(ht);
194 retval = zend_hash_del(TS_HASH(ht), key);
195 end_write(ht);
196
197 return retval;
198 }
199
zend_ts_hash_index_del(TsHashTable * ht,zend_ulong h)200 ZEND_API int zend_ts_hash_index_del(TsHashTable *ht, zend_ulong h)
201 {
202 int retval;
203
204 begin_write(ht);
205 retval = zend_hash_index_del(TS_HASH(ht), h);
206 end_write(ht);
207
208 return retval;
209 }
210
zend_ts_hash_find(TsHashTable * ht,zend_string * key)211 ZEND_API zval *zend_ts_hash_find(TsHashTable *ht, zend_string *key)
212 {
213 zval *retval;
214
215 begin_read(ht);
216 retval = zend_hash_find(TS_HASH(ht), key);
217 end_read(ht);
218
219 return retval;
220 }
221
zend_ts_hash_index_find(TsHashTable * ht,zend_ulong h)222 ZEND_API zval *zend_ts_hash_index_find(TsHashTable *ht, zend_ulong h)
223 {
224 zval *retval;
225
226 begin_read(ht);
227 retval = zend_hash_index_find(TS_HASH(ht), h);
228 end_read(ht);
229
230 return retval;
231 }
232
zend_ts_hash_exists(TsHashTable * ht,zend_string * key)233 ZEND_API int zend_ts_hash_exists(TsHashTable *ht, zend_string *key)
234 {
235 int retval;
236
237 begin_read(ht);
238 retval = zend_hash_exists(TS_HASH(ht), key);
239 end_read(ht);
240
241 return retval;
242 }
243
zend_ts_hash_index_exists(TsHashTable * ht,zend_ulong h)244 ZEND_API int zend_ts_hash_index_exists(TsHashTable *ht, zend_ulong h)
245 {
246 int retval;
247
248 begin_read(ht);
249 retval = zend_hash_index_exists(TS_HASH(ht), h);
250 end_read(ht);
251
252 return retval;
253 }
254
zend_ts_hash_copy(TsHashTable * target,TsHashTable * source,copy_ctor_func_t pCopyConstructor)255 ZEND_API void zend_ts_hash_copy(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor)
256 {
257 begin_read(source);
258 begin_write(target);
259 zend_hash_copy(TS_HASH(target), TS_HASH(source), pCopyConstructor);
260 end_write(target);
261 end_read(source);
262 }
263
zend_ts_hash_copy_to_hash(HashTable * target,TsHashTable * source,copy_ctor_func_t pCopyConstructor)264 ZEND_API void zend_ts_hash_copy_to_hash(HashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor)
265 {
266 begin_read(source);
267 zend_hash_copy(target, TS_HASH(source), pCopyConstructor);
268 end_read(source);
269 }
270
zend_ts_hash_merge(TsHashTable * target,TsHashTable * source,copy_ctor_func_t pCopyConstructor,int overwrite)271 ZEND_API void zend_ts_hash_merge(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor, int overwrite)
272 {
273 begin_read(source);
274 begin_write(target);
275 zend_hash_merge(TS_HASH(target), TS_HASH(source), pCopyConstructor, overwrite);
276 end_write(target);
277 end_read(source);
278 }
279
zend_ts_hash_merge_ex(TsHashTable * target,TsHashTable * source,copy_ctor_func_t pCopyConstructor,merge_checker_func_t pMergeSource,void * pParam)280 ZEND_API void zend_ts_hash_merge_ex(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor, merge_checker_func_t pMergeSource, void *pParam)
281 {
282 begin_read(source);
283 begin_write(target);
284 zend_hash_merge_ex(TS_HASH(target), TS_HASH(source), pCopyConstructor, pMergeSource, pParam);
285 end_write(target);
286 end_read(source);
287 }
288
zend_ts_hash_sort(TsHashTable * ht,sort_func_t sort_func,compare_func_t compare_func,int renumber)289 ZEND_API int zend_ts_hash_sort(TsHashTable *ht, sort_func_t sort_func, compare_func_t compare_func, int renumber)
290 {
291 int retval;
292
293 begin_write(ht);
294 retval = zend_hash_sort_ex(TS_HASH(ht), sort_func, compare_func, renumber);
295 end_write(ht);
296
297 return retval;
298 }
299
zend_ts_hash_compare(TsHashTable * ht1,TsHashTable * ht2,compare_func_t compar,zend_bool ordered)300 ZEND_API int zend_ts_hash_compare(TsHashTable *ht1, TsHashTable *ht2, compare_func_t compar, zend_bool ordered)
301 {
302 int retval;
303
304 begin_read(ht1);
305 begin_read(ht2);
306 retval = zend_hash_compare(TS_HASH(ht1), TS_HASH(ht2), compar, ordered);
307 end_read(ht2);
308 end_read(ht1);
309
310 return retval;
311 }
312
zend_ts_hash_minmax(TsHashTable * ht,compare_func_t compar,int flag)313 ZEND_API zval *zend_ts_hash_minmax(TsHashTable *ht, compare_func_t compar, int flag)
314 {
315 zval *retval;
316
317 begin_read(ht);
318 retval = zend_hash_minmax(TS_HASH(ht), compar, flag);
319 end_read(ht);
320
321 return retval;
322 }
323
zend_ts_hash_num_elements(TsHashTable * ht)324 ZEND_API int zend_ts_hash_num_elements(TsHashTable *ht)
325 {
326 int retval;
327
328 begin_read(ht);
329 retval = zend_hash_num_elements(TS_HASH(ht));
330 end_read(ht);
331
332 return retval;
333 }
334
zend_ts_hash_rehash(TsHashTable * ht)335 ZEND_API int zend_ts_hash_rehash(TsHashTable *ht)
336 {
337 int retval;
338
339 begin_write(ht);
340 retval = zend_hash_rehash(TS_HASH(ht));
341 end_write(ht);
342
343 return retval;
344 }
345
zend_ts_hash_str_find(TsHashTable * ht,const char * key,size_t len)346 ZEND_API zval *zend_ts_hash_str_find(TsHashTable *ht, const char *key, size_t len)
347 {
348 zval *retval;
349
350 begin_read(ht);
351 retval = zend_hash_str_find(TS_HASH(ht), key, len);
352 end_read(ht);
353
354 return retval;
355 }
356
zend_ts_hash_str_update(TsHashTable * ht,const char * key,size_t len,zval * pData)357 ZEND_API zval *zend_ts_hash_str_update(TsHashTable *ht, const char *key, size_t len, zval *pData)
358 {
359 zval *retval;
360
361 begin_write(ht);
362 retval = zend_hash_str_update(TS_HASH(ht), key, len, pData);
363 end_write(ht);
364
365 return retval;
366 }
367
zend_ts_hash_str_add(TsHashTable * ht,const char * key,size_t len,zval * pData)368 ZEND_API zval *zend_ts_hash_str_add(TsHashTable *ht, const char *key, size_t len, zval *pData)
369 {
370 zval *retval;
371
372 begin_write(ht);
373 retval = zend_hash_str_add(TS_HASH(ht), key, len, pData);
374 end_write(ht);
375
376 return retval;
377 }
378
379 /*
380 * Local variables:
381 * tab-width: 4
382 * c-basic-offset: 4
383 * indent-tabs-mode: t
384 * End:
385 */
386