Change #12623 inflicted an infinite hang. Fixed.
[p5sagit/p5-mst-13.2.git] / ext / threads / shared / shared.xs
CommitLineData
b050c948 1
2#include "EXTERN.h"
3#include "perl.h"
4#include "XSUB.h"
5
6
7void shared_sv_attach_sv (SV* sv, shared_sv* shared) {
8 HV* shared_hv = get_hv("threads::shared::shared", FALSE);
9 SV* id = newSViv((IV)shared);
10 STRLEN length = sv_len(id);
11 SV* tiedobject;
12 SV** tiedobject_ = hv_fetch(shared_hv, SvPV(id,length), length, 0);
13 if(tiedobject_) {
14 tiedobject = (*tiedobject_);
15 SvROK_on(sv);
16 SvRV(sv) = SvRV(tiedobject);
17
18 } else {
19 croak("die\n");
20 }
21}
22
23
24int shared_sv_fetch_mg (pTHX_ SV* sv, MAGIC *mg) {
25 shared_sv* shared = (shared_sv*) SvIV(mg->mg_obj);
26 SHAREDSvLOCK(shared);
55fc11ad 27 if(mg->mg_private != shared->index) {
28 if(SvROK(SHAREDSvGET(shared))) {
29 shared_sv* target = (shared_sv*) SvIV(SvRV(SHAREDSvGET(shared)));
30 shared_sv_attach_sv(sv, target);
31 } else {
32 sv_setsv(sv, SHAREDSvGET(shared));
33 }
34 mg->mg_private = shared->index;
b050c948 35 }
36 SHAREDSvUNLOCK(shared);
37
38 return 0;
39}
40
41int shared_sv_store_mg (pTHX_ SV* sv, MAGIC *mg) {
42 shared_sv* shared = (shared_sv*) SvIV(mg->mg_obj);
43 SHAREDSvLOCK(shared);
44 if(SvROK(SHAREDSvGET(shared)))
45 Perl_sharedsv_thrcnt_dec(aTHX_ (shared_sv*) SvIV(SvRV(SHAREDSvGET(shared))));
b050c948 46 if(SvROK(sv)) {
47 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(sv));
48 if(!target) {
b050c948 49 sv_setsv(sv,SHAREDSvGET(shared));
50 SHAREDSvUNLOCK(shared);
51 Perl_croak(aTHX_ "You cannot assign a non shared reference to a shared scalar");
52 }
f70d29d4 53 SHAREDSvEDIT(shared);
b050c948 54 Perl_sv_free(PL_sharedsv_space,SHAREDSvGET(shared));
55 SHAREDSvGET(shared) = newRV_noinc(newSViv((IV)target));
b050c948 56 } else {
f70d29d4 57 SHAREDSvEDIT(shared);
58 sv_setsv(SHAREDSvGET(shared), sv);
b050c948 59 }
55fc11ad 60 shared->index++;
61 mg->mg_private = shared->index;
b050c948 62 SHAREDSvRELEASE(shared);
63 if(SvROK(SHAREDSvGET(shared)))
64 Perl_sharedsv_thrcnt_inc(aTHX_ (shared_sv*) SvIV(SvRV(SHAREDSvGET(shared))));
65 SHAREDSvUNLOCK(shared);
66 return 0;
67}
68
69int shared_sv_destroy_mg (pTHX_ SV* sv, MAGIC *mg) {
70 shared_sv* shared = (shared_sv*) SvIV(mg->mg_obj);
71 if(!shared)
72 return 0;
73 Perl_sharedsv_thrcnt_dec(aTHX_ shared);
74}
75
76MGVTBL svtable = {MEMBER_TO_FPTR(shared_sv_fetch_mg),
77 MEMBER_TO_FPTR(shared_sv_store_mg),
78 0,
79 0,
80 MEMBER_TO_FPTR(shared_sv_destroy_mg)
81};
82
83MODULE = threads::shared PACKAGE = threads::shared
84
85
86PROTOTYPES: DISABLE
87
88
89SV*
90ptr(ref)
91 SV* ref
92 CODE:
93 RETVAL = newSViv(SvIV(SvRV(ref)));
94 OUTPUT:
95 RETVAL
96
97
98SV*
99_thrcnt(ref)
100 SV* ref
101 CODE:
102 shared_sv* shared = Perl_sharedsv_find(aTHX, ref);
103 if(!shared)
104 croak("thrcnt can only be used on shared values");
105 SHAREDSvLOCK(shared);
106 RETVAL = newSViv(SvREFCNT(SHAREDSvGET(shared)));
107 SHAREDSvUNLOCK(shared);
108 OUTPUT:
109 RETVAL
110
111
112void
113thrcnt_inc(ref)
114 SV* ref
115 CODE:
116 shared_sv* shared;
117 if(SvROK(ref))
118 ref = SvRV(ref);
119 shared = Perl_sharedsv_find(aTHX, ref);
120 if(!shared)
121 croak("thrcnt can only be used on shared values");
122 Perl_sharedsv_thrcnt_inc(aTHX_ shared);
123
124
125MODULE = threads::shared PACKAGE = threads::shared::sv
126
127SV*
128new(class, value)
129 SV* class
130 SV* value
131 CODE:
132 shared_sv* shared = Perl_sharedsv_new(aTHX);
133 MAGIC* shared_magic;
134 SV* obj = newSViv((IV)shared);
135 SHAREDSvEDIT(shared);
136 SHAREDSvGET(shared) = newSVsv(value);
137 SHAREDSvRELEASE(shared);
138 sv_magic(value, 0, PERL_MAGIC_ext, "threads::shared", 16);
139 shared_magic = mg_find(value, PERL_MAGIC_ext);
140 shared_magic->mg_virtual = &svtable;
141 shared_magic->mg_obj = newSViv((IV)shared);
142 shared_magic->mg_flags |= MGf_REFCOUNTED;
55fc11ad 143 shared_magic->mg_private = 0;
b050c948 144 SvMAGICAL_on(value);
145 RETVAL = obj;
146 OUTPUT:
147 RETVAL
148
149
aaf3876d 150MODULE = threads::shared PACKAGE = threads::shared::av
151
152SV*
153new(class, value)
154 SV* class
155 SV* value
156 CODE:
157 shared_sv* shared = Perl_sharedsv_new(aTHX);
158 SV* obj = newSViv((IV)shared);
159 SHAREDSvEDIT(shared);
160 SHAREDSvGET(shared) = (SV*) newAV();
161 SHAREDSvRELEASE(shared);
162 RETVAL = obj;
163 OUTPUT:
164 RETVAL
165
166void
167STORE(self, index, value)
168 SV* self
169 SV* index
170 SV* value
171 CODE:
172 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
173 shared_sv* slot;
174 SV* aentry;
175 SV** aentry_;
176 SHAREDSvLOCK(shared);
177 aentry_ = av_fetch((AV*) SHAREDSvGET(shared), SvIV(index), 0);
178 if(aentry_ && SvIV((*aentry_))) {
179 aentry = (*aentry_);
180 slot = (shared_sv*) SvIV(aentry);
181 if(SvROK(SHAREDSvGET(slot)))
182 Perl_sharedsv_thrcnt_dec(aTHX_ (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot))));
183 SHAREDSvEDIT(slot);
184 sv_setsv(SHAREDSvGET(slot), value);
185 SHAREDSvRELEASE(slot);
186 } else {
187 slot = Perl_sharedsv_new(aTHX);
188 SHAREDSvEDIT(shared);
189 SHAREDSvGET(slot) = newSVsv(value);
190 aentry = newSViv((IV)slot);
191 av_store((AV*) SHAREDSvGET(shared), SvIV(index), aentry);
192 SHAREDSvRELEASE(shared);
193 }
194 SHAREDSvUNLOCK(shared);
195
196SV*
197FETCH(self, index)
198 SV* self
199 SV* index
200 CODE:
201 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
202 shared_sv* slot;
203 SV* aentry;
204 SV** aentry_;
205 SV* retval;
206 SHAREDSvLOCK(shared);
207 aentry_ = av_fetch((AV*) SHAREDSvGET(shared), SvIV(index),0);
208 if(aentry_) {
209 aentry = (*aentry_);
210 if(SvTYPE(aentry) == SVt_NULL) {
211 retval = &PL_sv_undef;
212 } else {
213 slot = (shared_sv*) SvIV(aentry);
214 retval = newSVsv(SHAREDSvGET(slot));
215 }
216 } else {
217 retval = &PL_sv_undef;
218 }
219 SHAREDSvUNLOCK(shared);
220 RETVAL = retval;
221 OUTPUT:
222 RETVAL
223
224void
225PUSH(self, ...)
226 SV* self
227 CODE:
228 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
229 int i;
230 SHAREDSvLOCK(shared);
231 for(i = 1; i < items; i++) {
232 shared_sv* slot = Perl_sharedsv_new(aTHX);
233 SV* tmp = ST(i);
234 SHAREDSvEDIT(slot);
235 SHAREDSvGET(slot) = newSVsv(tmp);
236 av_push((AV*) SHAREDSvGET(shared), newSViv((IV)slot));
237 SHAREDSvRELEASE(slot);
238 }
239 SHAREDSvUNLOCK(shared);
240
241void
242UNSHIFT(self, ...)
243 SV* self
244 CODE:
245 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
246 int i;
247 SHAREDSvLOCK(shared);
248 SHAREDSvEDIT(shared);
249 av_unshift((AV*)SHAREDSvGET(shared), items - 1);
250 SHAREDSvRELEASE(shared);
251 for(i = 1; i < items; i++) {
252 shared_sv* slot = Perl_sharedsv_new(aTHX);
253 SV* tmp = ST(i);
254 SHAREDSvEDIT(slot);
255 SHAREDSvGET(slot) = newSVsv(tmp);
256 av_store((AV*) SHAREDSvGET(shared), i - 1, newSViv((IV)slot));
257 SHAREDSvRELEASE(slot);
258 }
259 SHAREDSvUNLOCK(shared);
260
261SV*
262POP(self)
263 SV* self
264 CODE:
265 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
266 shared_sv* slot;
267 SV* retval;
268 SHAREDSvLOCK(shared);
269 SHAREDSvEDIT(shared);
270 retval = av_pop((AV*)SHAREDSvGET(shared));
271 SHAREDSvRELEASE(shared);
272 if(retval && SvIV(retval)) {
273 slot = (shared_sv*) SvIV(retval);
274 retval = newSVsv(SHAREDSvGET(slot));
275 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
276 } else {
277 retval = &PL_sv_undef;
278 }
279 SHAREDSvUNLOCK(shared);
280 RETVAL = retval;
281 OUTPUT:
282 RETVAL
283
284
285SV*
286SHIFT(self)
287 SV* self
288 CODE:
289 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
290 shared_sv* slot;
291 SV* retval;
292 SHAREDSvLOCK(shared);
293 SHAREDSvEDIT(shared);
294 retval = av_shift((AV*)SHAREDSvGET(shared));
295 SHAREDSvRELEASE(shared);
296 if(retval && SvIV(retval)) {
297 slot = (shared_sv*) SvIV(retval);
298 retval = newSVsv(SHAREDSvGET(slot));
299 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
300 } else {
301 retval = &PL_sv_undef;
302 }
303 SHAREDSvUNLOCK(shared);
304 RETVAL = retval;
305 OUTPUT:
306 RETVAL
307
308void
309CLEAR(self)
310 SV* self
311 CODE:
312 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
313 shared_sv* slot;
314 SV** svp;
315 I32 i;
316 SHAREDSvLOCK(shared);
317 svp = AvARRAY((AV*)SHAREDSvGET(shared));
318 i = AvFILLp((AV*)SHAREDSvGET(shared));
319 while ( i >= 0) {
320 if(SvIV(svp[i])) {
321 Perl_sharedsv_thrcnt_dec(aTHX_ (shared_sv*) SvIV(svp[i]));
322 }
323 i--;
324 }
325 SHAREDSvEDIT(shared);
326 av_clear((AV*)SHAREDSvGET(shared));
327 SHAREDSvRELEASE(shared);
328 SHAREDSvUNLOCK(shared);
329
330void
331EXTEND(self, count)
332 SV* self
333 SV* count
334 CODE:
335 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
336 SHAREDSvEDIT(shared);
337 av_extend((AV*)SHAREDSvGET(shared), (I32) SvIV(count));
338 SHAREDSvRELEASE(shared);
339
340
341
342
343SV*
344EXISTS(self, index)
345 SV* self
346 SV* index
347 CODE:
348 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
349 I32 exists;
350 SHAREDSvLOCK(shared);
351 exists = av_exists((AV*) SHAREDSvGET(shared), (I32) SvIV(index));
352 if(exists) {
353 RETVAL = &PL_sv_yes;
354 } else {
355 RETVAL = &PL_sv_no;
356 }
357 SHAREDSvUNLOCK(shared);
358
359void
360STORESIZE(self,count)
361 SV* self
362 SV* count
363 CODE:
364 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
365 SHAREDSvEDIT(shared);
366 av_fill((AV*) SHAREDSvGET(shared), (I32) SvIV(count));
367 SHAREDSvRELEASE(shared);
368
369SV*
370FETCHSIZE(self)
371 SV* self
372 CODE:
373 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
374 SHAREDSvLOCK(shared);
375 RETVAL = newSViv(av_len((AV*) SHAREDSvGET(shared)) + 1);
376 SHAREDSvUNLOCK(shared);
377 OUTPUT:
378 RETVAL
379
380SV*
381DELETE(self,index)
382 SV* self
383 SV* index
384 CODE:
385 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
386 shared_sv* slot;
387 SHAREDSvLOCK(shared);
388 if(av_exists((AV*) SHAREDSvGET(shared), (I32) SvIV(index))) {
389 SV* tmp;
390 SHAREDSvEDIT(shared);
391 tmp = av_delete((AV*)SHAREDSvGET(shared), (I32) SvIV(index),0);
392 SHAREDSvRELEASE(shared);
393 if(SvIV(tmp)) {
394 slot = (shared_sv*) SvIV(tmp);
395 RETVAL = newSVsv(SHAREDSvGET(slot));
396 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
397 } else {
398 RETVAL = &PL_sv_undef;
399 }
400 } else {
401 RETVAL = &PL_sv_undef;
402 }
403 SHAREDSvUNLOCK(shared);
404 OUTPUT:
405 RETVAL
406
407AV*
408SPLICE(self, offset, length, ...)
409 SV* self
410 SV* offset
411 SV* length
412 CODE:
413 croak("Splice is not implmented for shared arrays");
414
8669ce85 415MODULE = threads::shared PACKAGE = threads::shared::hv
aaf3876d 416
8669ce85 417SV*
418new(class, value)
419 SV* class
420 SV* value
421 CODE:
422 shared_sv* shared = Perl_sharedsv_new(aTHX);
423 SV* obj = newSViv((IV)shared);
424 SHAREDSvEDIT(shared);
425 SHAREDSvGET(shared) = (SV*) newHV();
426 SHAREDSvRELEASE(shared);
427 RETVAL = obj;
428 OUTPUT:
429 RETVAL
430
431void
432STORE(self, key, value)
433 SV* self
434 SV* key
435 SV* value
436 CODE:
437 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
438 shared_sv* slot;
439 SV* hentry;
440 SV** hentry_;
441 STRLEN len;
442 char* ckey = SvPV(key, len);
443 SHAREDSvLOCK(shared);
444 hentry_ = hv_fetch((HV*) SHAREDSvGET(shared), ckey, len, 0);
445 if(hentry_ && SvIV((*hentry_))) {
446 hentry = (*hentry_);
447 slot = (shared_sv*) SvIV(hentry);
448 if(SvROK(SHAREDSvGET(slot)))
449 Perl_sharedsv_thrcnt_dec(aTHX_ (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot))));
450 SHAREDSvEDIT(slot);
451 sv_setsv(SHAREDSvGET(slot), value);
452 SHAREDSvRELEASE(slot);
453 } else {
454 slot = Perl_sharedsv_new(aTHX);
455 SHAREDSvEDIT(shared);
456 SHAREDSvGET(slot) = newSVsv(value);
457 hentry = newSViv((IV)slot);
458 hv_store((HV*) SHAREDSvGET(shared), ckey,len , hentry, 0);
459 SHAREDSvRELEASE(shared);
460 }
461 SHAREDSvUNLOCK(shared);
462
463
464SV*
465FETCH(self, key)
466 SV* self
467 SV* key
468 CODE:
469 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
470 shared_sv* slot;
471 SV* hentry;
472 SV** hentry_;
473 SV* retval;
474 STRLEN len;
475 char* ckey = SvPV(key, len);
476 SHAREDSvLOCK(shared);
477 hentry_ = hv_fetch((HV*) SHAREDSvGET(shared), ckey, len,0);
478 if(hentry_) {
479 hentry = (*hentry_);
480 if(SvTYPE(hentry) == SVt_NULL) {
481 retval = &PL_sv_undef;
482 } else {
483 slot = (shared_sv*) SvIV(hentry);
484 retval = newSVsv(SHAREDSvGET(slot));
485 }
486 } else {
487 retval = &PL_sv_undef;
488 }
489 SHAREDSvUNLOCK(shared);
490 RETVAL = retval;
491 OUTPUT:
492 RETVAL
493
494void
495CLEAR(self)
496 SV* self
497 CODE:
498 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
499 shared_sv* slot;
500 HE* entry;
501 SHAREDSvLOCK(shared);
502 Perl_hv_iterinit(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
503 entry = Perl_hv_iternext(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
504 while(entry) {
505 slot = (shared_sv*) SvIV(Perl_hv_iterval(PL_sharedsv_space, (HV*) SHAREDSvGET(shared), entry));
506 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
507 entry = Perl_hv_iternext(PL_sharedsv_space,(HV*) SHAREDSvGET(shared));
508 }
509 SHAREDSvEDIT(shared);
510 hv_clear((HV*) SHAREDSvGET(shared));
511 SHAREDSvRELEASE(shared);
512 SHAREDSvUNLOCK(shared);
513
514SV*
515FIRSTKEY(self)
516 SV* self
517 CODE:
518 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
519 char* key = NULL;
520 I32 len;
521 HE* entry;
522 SHAREDSvLOCK(shared);
523 Perl_hv_iterinit(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
524 entry = Perl_hv_iternext(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
525 if(entry) {
526 key = Perl_hv_iterkey(PL_sharedsv_space, entry,&len);
527 RETVAL = newSVpv(key, len);
528 } else {
529 RETVAL = &PL_sv_undef;
530 }
531 SHAREDSvUNLOCK(shared);
532 OUTPUT:
533 RETVAL
534
535
536SV*
537NEXTKEY(self, oldkey)
538 SV* self
539 SV* oldkey
540 CODE:
541 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
542 char* key = NULL;
543 I32 len;
544 HE* entry;
545 SHAREDSvLOCK(shared);
546 entry = Perl_hv_iternext(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
547 if(entry) {
548 key = Perl_hv_iterkey(PL_sharedsv_space, entry,&len);
549 RETVAL = newSVpv(key, len);
550 } else {
551 RETVAL = &PL_sv_undef;
552 }
553 SHAREDSvUNLOCK(shared);
554 OUTPUT:
555 RETVAL
556
557
558SV*
559EXISTS(self, key)
560 SV* self
561 SV* key
562 CODE:
563 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
564 STRLEN len;
565 char* ckey = SvPV(key, len);
566 SHAREDSvLOCK(shared);
567 if(hv_exists((HV*)SHAREDSvGET(shared), ckey, len)) {
568 RETVAL = &PL_sv_yes;
569 } else {
570 RETVAL = &PL_sv_no;
571 }
572 SHAREDSvUNLOCK(shared);
573 OUTPUT:
574 RETVAL
575
576SV*
577DELETE(self, key)
578 SV* self
579 SV* key
580 CODE:
581 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
582 shared_sv* slot;
583 STRLEN len;
584 char* ckey = SvPV(key, len);
585 SV* tmp;
586 SHAREDSvLOCK(shared);
587 SHAREDSvEDIT(shared);
588 tmp = hv_delete((HV*) SHAREDSvGET(shared), ckey, len,0);
589 SHAREDSvRELEASE(shared);
590 if(tmp) {
591 slot = SvIV(tmp);
592 RETVAL = newSVsv(SHAREDSvGET(slot));
593 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
594 } else {
595 RETVAL = &PL_sv_undef;
596 }
597 SHAREDSvUNLOCK(shared);
598 OUTPUT:
599 RETVAL