8 SV* shared_sv_attach_sv (SV* sv, shared_sv* shared) {
9 HV* shared_hv = get_hv("threads::shared::shared", FALSE);
10 SV* id = newSViv((IV)shared);
11 STRLEN length = sv_len(id);
13 SV** tiedobject_ = hv_fetch(shared_hv, SvPV(id,length), length, 0);
15 tiedobject = (*tiedobject_);
18 SvRV(sv) = SvRV(tiedobject);
20 sv = newRV(SvRV(tiedobject));
23 switch(SvTYPE(SHAREDSvGET(shared))) {
26 SV* obj_ref = newSViv(0);
27 SV* obj = newSVrv(obj_ref,"threads::shared::av");
29 sv_setiv(obj,(IV)shared);
30 weakref = newRV((SV*)hv);
31 sv = newRV_noinc((SV*)hv);
33 sv_magic((SV*) hv, obj_ref, PERL_MAGIC_tied, Nullch, 0);
34 hv_store(shared_hv, SvPV(id,length), length, weakref, 0);
35 Perl_sharedsv_thrcnt_inc(aTHX_ shared);
40 SV* obj_ref = newSViv(0);
41 SV* obj = newSVrv(obj_ref,"threads::shared::hv");
43 sv_setiv(obj,(IV)shared);
44 weakref = newRV((SV*)hv);
45 sv = newRV_noinc((SV*)hv);
47 sv_magic((SV*) hv, obj_ref, PERL_MAGIC_tied, Nullch, 0);
48 hv_store(shared_hv, SvPV(id,length), length, weakref, 0);
49 Perl_sharedsv_thrcnt_inc(aTHX_ shared);
54 SV* value = newSVsv(SHAREDSvGET(shared));
55 SV* obj = newSViv((IV)shared);
56 sv_magic(value, 0, PERL_MAGIC_ext, "threads::shared", 16);
57 shared_magic = mg_find(value, PERL_MAGIC_ext);
58 shared_magic->mg_virtual = &svtable;
59 shared_magic->mg_obj = newSViv((IV)shared);
60 shared_magic->mg_flags |= MGf_REFCOUNTED;
61 shared_magic->mg_private = 0;
63 sv = newRV_noinc(value);
66 hv_store(shared_hv, SvPV(id,length),length, value, 0);
67 Perl_sharedsv_thrcnt_inc(aTHX_ shared);
76 int shared_sv_fetch_mg (pTHX_ SV* sv, MAGIC *mg) {
77 shared_sv* shared = (shared_sv*) SvIV(mg->mg_obj);
79 if(mg->mg_private != shared->index) {
80 if(SvROK(SHAREDSvGET(shared))) {
81 shared_sv* target = (shared_sv*) SvIV(SvRV(SHAREDSvGET(shared)));
82 shared_sv_attach_sv(sv, target);
84 sv_setsv(sv, SHAREDSvGET(shared));
86 mg->mg_private = shared->index;
88 SHAREDSvUNLOCK(shared);
93 int shared_sv_store_mg (pTHX_ SV* sv, MAGIC *mg) {
94 shared_sv* shared = (shared_sv*) SvIV(mg->mg_obj);
96 if(SvROK(SHAREDSvGET(shared)))
97 Perl_sharedsv_thrcnt_dec(aTHX_ (shared_sv*) SvIV(SvRV(SHAREDSvGET(shared))));
99 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(sv));
101 sv_setsv(sv,SHAREDSvGET(shared));
102 SHAREDSvUNLOCK(shared);
103 Perl_croak(aTHX_ "You cannot assign a non shared reference to a shared scalar");
105 SHAREDSvEDIT(shared);
106 Perl_sv_free(PL_sharedsv_space,SHAREDSvGET(shared));
107 SHAREDSvGET(shared) = newRV_noinc(newSViv((IV)target));
109 SHAREDSvEDIT(shared);
110 sv_setsv(SHAREDSvGET(shared), sv);
113 mg->mg_private = shared->index;
114 SHAREDSvRELEASE(shared);
115 if(SvROK(SHAREDSvGET(shared)))
116 Perl_sharedsv_thrcnt_inc(aTHX_ (shared_sv*) SvIV(SvRV(SHAREDSvGET(shared))));
117 SHAREDSvUNLOCK(shared);
121 int shared_sv_destroy_mg (pTHX_ SV* sv, MAGIC *mg) {
122 shared_sv* shared = (shared_sv*) SvIV(mg->mg_obj);
126 HV* shared_hv = get_hv("threads::shared::shared", FALSE);
127 SV* id = newSViv((IV)shared);
128 STRLEN length = sv_len(id);
129 hv_delete(shared_hv, SvPV(id,length), length,0);
131 Perl_sharedsv_thrcnt_dec(aTHX_ shared);
134 MGVTBL svtable = {MEMBER_TO_FPTR(shared_sv_fetch_mg),
135 MEMBER_TO_FPTR(shared_sv_store_mg),
138 MEMBER_TO_FPTR(shared_sv_destroy_mg)
141 MODULE = threads::shared PACKAGE = threads::shared
151 RETVAL = newSViv(SvIV(SvRV(ref)));
163 shared = Perl_sharedsv_find(aTHX, ref);
165 croak("thrcnt can only be used on shared values");
166 SHAREDSvLOCK(shared);
167 RETVAL = newSViv(SvREFCNT(SHAREDSvGET(shared)));
168 SHAREDSvUNLOCK(shared);
180 shared = Perl_sharedsv_find(aTHX, ref);
182 croak("thrcnt can only be used on shared values");
183 Perl_sharedsv_thrcnt_inc(aTHX_ shared);
189 shared_sv* shared = (shared_sv*) SvIV(ref);
191 croak("thrcnt can only be used on shared values");
192 Perl_sharedsv_thrcnt_dec(aTHX_ shared);
202 shared = Perl_sharedsv_find(aTHX, ref);
204 croak("unlock can only be used on shared values");
205 SHAREDSvUNLOCK(shared);
215 shared = Perl_sharedsv_find(aTHX, ref);
217 croak("lock can only be used on shared values");
218 SHAREDSvLOCK(shared);
222 cond_wait_enabled(ref)
229 shared = Perl_sharedsv_find(aTHX_ ref);
231 croak("cond_wait can only be used on shared values");
232 if(shared->owner != PERL_GET_CONTEXT)
233 croak("You need a lock before you can cond_wait");
234 MUTEX_LOCK(&shared->mutex);
235 shared->owner = NULL;
236 locks = shared->locks = 0;
237 COND_WAIT(&shared->user_cond, &shared->mutex);
238 shared->owner = PERL_GET_CONTEXT;
239 shared->locks = locks;
241 void cond_signal_enabled(ref)
247 shared = Perl_sharedsv_find(aTHX_ ref);
249 croak("cond_signal can only be used on shared values");
250 COND_SIGNAL(&shared->user_cond);
253 void cond_broadcast_enabled(ref)
259 shared = Perl_sharedsv_find(aTHX_ ref);
261 croak("cond_broadcast can only be used on shared values");
262 COND_BROADCAST(&shared->user_cond);
264 MODULE = threads::shared PACKAGE = threads::shared::sv
271 shared_sv* shared = Perl_sharedsv_new(aTHX);
273 SV* obj = newSViv((IV)shared);
274 SHAREDSvEDIT(shared);
275 SHAREDSvGET(shared) = newSVsv(value);
276 SHAREDSvRELEASE(shared);
277 sv_magic(value, 0, PERL_MAGIC_ext, "threads::shared", 16);
278 shared_magic = mg_find(value, PERL_MAGIC_ext);
279 shared_magic->mg_virtual = &svtable;
280 shared_magic->mg_obj = newSViv((IV)shared);
281 shared_magic->mg_flags |= MGf_REFCOUNTED;
282 shared_magic->mg_private = 0;
289 MODULE = threads::shared PACKAGE = threads::shared::av
296 shared_sv* shared = Perl_sharedsv_new(aTHX);
297 SV* obj = newSViv((IV)shared);
298 SHAREDSvEDIT(shared);
299 SHAREDSvGET(shared) = (SV*) newAV();
300 SHAREDSvRELEASE(shared);
306 STORE(self, index, value)
311 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
316 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(value));
318 Perl_croak(aTHX_ "You cannot assign a non shared reference to an shared array");
320 value = newRV_noinc(newSViv((IV)target));
322 SHAREDSvLOCK(shared);
323 aentry_ = av_fetch((AV*) SHAREDSvGET(shared), SvIV(index), 0);
324 if(aentry_ && SvIV((*aentry_))) {
326 slot = (shared_sv*) SvIV(aentry);
327 if(SvROK(SHAREDSvGET(slot)))
328 Perl_sharedsv_thrcnt_dec(aTHX_ (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot))));
330 sv_setsv(SHAREDSvGET(slot), value);
331 SHAREDSvRELEASE(slot);
333 slot = Perl_sharedsv_new(aTHX);
334 SHAREDSvEDIT(shared);
335 SHAREDSvGET(slot) = newSVsv(value);
336 aentry = newSViv((IV)slot);
337 av_store((AV*) SHAREDSvGET(shared), SvIV(index), aentry);
338 SHAREDSvRELEASE(shared);
340 if(SvROK(SHAREDSvGET(slot)))
341 Perl_sharedsv_thrcnt_inc(aTHX_ (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot))));
343 SHAREDSvUNLOCK(shared);
350 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
355 SHAREDSvLOCK(shared);
356 aentry_ = av_fetch((AV*) SHAREDSvGET(shared), SvIV(index),0);
359 if(SvTYPE(aentry) == SVt_NULL) {
360 retval = &PL_sv_undef;
362 slot = (shared_sv*) SvIV(aentry);
363 if(SvROK(SHAREDSvGET(slot))) {
364 shared_sv* target = (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot)));
365 retval = shared_sv_attach_sv(NULL,target);
367 retval = newSVsv(SHAREDSvGET(slot));
371 retval = &PL_sv_undef;
373 SHAREDSvUNLOCK(shared);
382 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
384 SHAREDSvLOCK(shared);
385 for(i = 1; i < items; i++) {
386 shared_sv* slot = Perl_sharedsv_new(aTHX);
389 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(tmp));
391 Perl_croak(aTHX_ "You cannot assign a non shared reference to an shared array");
393 tmp = newRV_noinc(newSViv((IV)target));
396 SHAREDSvGET(slot) = newSVsv(tmp);
397 av_push((AV*) SHAREDSvGET(shared), newSViv((IV)slot));
398 SHAREDSvRELEASE(slot);
399 if(SvROK(SHAREDSvGET(slot)))
400 Perl_sharedsv_thrcnt_inc(aTHX_ (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot))));
402 SHAREDSvUNLOCK(shared);
408 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
410 SHAREDSvLOCK(shared);
411 SHAREDSvEDIT(shared);
412 av_unshift((AV*)SHAREDSvGET(shared), items - 1);
413 SHAREDSvRELEASE(shared);
414 for(i = 1; i < items; i++) {
415 shared_sv* slot = Perl_sharedsv_new(aTHX);
418 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(tmp));
420 Perl_croak(aTHX_ "You cannot assign a non shared reference to an shared array");
422 tmp = newRV_noinc(newSViv((IV)target));
425 SHAREDSvGET(slot) = newSVsv(tmp);
426 av_store((AV*) SHAREDSvGET(shared), i - 1, newSViv((IV)slot));
427 SHAREDSvRELEASE(slot);
428 if(SvROK(SHAREDSvGET(slot)))
429 Perl_sharedsv_thrcnt_inc(aTHX_ (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot))));
431 SHAREDSvUNLOCK(shared);
437 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
440 SHAREDSvLOCK(shared);
441 SHAREDSvEDIT(shared);
442 retval = av_pop((AV*)SHAREDSvGET(shared));
443 SHAREDSvRELEASE(shared);
444 if(retval && SvIV(retval)) {
445 slot = (shared_sv*) SvIV(retval);
446 if(SvROK(SHAREDSvGET(slot))) {
447 shared_sv* target = (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot)));
448 retval = shared_sv_attach_sv(NULL,target);
450 retval = newSVsv(SHAREDSvGET(slot));
452 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
454 retval = &PL_sv_undef;
456 SHAREDSvUNLOCK(shared);
466 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
469 SHAREDSvLOCK(shared);
470 SHAREDSvEDIT(shared);
471 retval = av_shift((AV*)SHAREDSvGET(shared));
472 SHAREDSvRELEASE(shared);
473 if(retval && SvIV(retval)) {
474 slot = (shared_sv*) SvIV(retval);
475 if(SvROK(SHAREDSvGET(slot))) {
476 shared_sv* target = (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot)));
477 retval = shared_sv_attach_sv(NULL,target);
479 retval = newSVsv(SHAREDSvGET(slot));
481 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
483 retval = &PL_sv_undef;
485 SHAREDSvUNLOCK(shared);
494 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
498 SHAREDSvLOCK(shared);
499 svp = AvARRAY((AV*)SHAREDSvGET(shared));
500 i = AvFILLp((AV*)SHAREDSvGET(shared));
503 Perl_sharedsv_thrcnt_dec(aTHX_ (shared_sv*) SvIV(svp[i]));
507 SHAREDSvEDIT(shared);
508 av_clear((AV*)SHAREDSvGET(shared));
509 SHAREDSvRELEASE(shared);
510 SHAREDSvUNLOCK(shared);
517 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
518 SHAREDSvEDIT(shared);
519 av_extend((AV*)SHAREDSvGET(shared), (I32) SvIV(count));
520 SHAREDSvRELEASE(shared);
530 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
532 SHAREDSvLOCK(shared);
533 exists = av_exists((AV*) SHAREDSvGET(shared), (I32) SvIV(index));
539 SHAREDSvUNLOCK(shared);
542 STORESIZE(self,count)
546 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
547 SHAREDSvEDIT(shared);
548 av_fill((AV*) SHAREDSvGET(shared), (I32) SvIV(count));
549 SHAREDSvRELEASE(shared);
555 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
556 SHAREDSvLOCK(shared);
557 RETVAL = newSViv(av_len((AV*) SHAREDSvGET(shared)) + 1);
558 SHAREDSvUNLOCK(shared);
567 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
569 SHAREDSvLOCK(shared);
570 if(av_exists((AV*) SHAREDSvGET(shared), (I32) SvIV(index))) {
572 SHAREDSvEDIT(shared);
573 tmp = av_delete((AV*)SHAREDSvGET(shared), (I32) SvIV(index),0);
574 SHAREDSvRELEASE(shared);
576 slot = (shared_sv*) SvIV(tmp);
577 if(SvROK(SHAREDSvGET(slot))) {
578 shared_sv* target = (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot)));
579 RETVAL = shared_sv_attach_sv(NULL,target);
581 RETVAL = newSVsv(SHAREDSvGET(slot));
583 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
585 RETVAL = &PL_sv_undef;
588 RETVAL = &PL_sv_undef;
590 SHAREDSvUNLOCK(shared);
595 SPLICE(self, offset, length, ...)
600 croak("Splice is not implmented for shared arrays");
602 MODULE = threads::shared PACKAGE = threads::shared::hv
609 shared_sv* shared = Perl_sharedsv_new(aTHX);
610 SV* obj = newSViv((IV)shared);
611 SHAREDSvEDIT(shared);
612 SHAREDSvGET(shared) = (SV*) newHV();
613 SHAREDSvRELEASE(shared);
619 STORE(self, key, value)
624 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
629 char* ckey = SvPV(key, len);
630 SHAREDSvLOCK(shared);
632 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(value));
634 Perl_croak(aTHX_ "You cannot assign a non shared reference to a shared hash");
636 SHAREDSvEDIT(shared);
637 value = newRV_noinc(newSViv((IV)target));
638 SHAREDSvRELEASE(shared);
640 hentry_ = hv_fetch((HV*) SHAREDSvGET(shared), ckey, len, 0);
641 if(hentry_ && SvIV((*hentry_))) {
643 slot = (shared_sv*) SvIV(hentry);
644 if(SvROK(SHAREDSvGET(slot)))
645 Perl_sharedsv_thrcnt_dec(aTHX_ (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot))));
647 sv_setsv(SHAREDSvGET(slot), value);
648 SHAREDSvRELEASE(slot);
650 slot = Perl_sharedsv_new(aTHX);
651 SHAREDSvEDIT(shared);
652 SHAREDSvGET(slot) = newSVsv(value);
653 hentry = newSViv((IV)slot);
654 hv_store((HV*) SHAREDSvGET(shared), ckey,len , hentry, 0);
655 SHAREDSvRELEASE(shared);
657 if(SvROK(SHAREDSvGET(slot)))
658 Perl_sharedsv_thrcnt_inc(aTHX_ (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot))));
659 SHAREDSvUNLOCK(shared);
667 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
673 char* ckey = SvPV(key, len);
674 SHAREDSvLOCK(shared);
675 hentry_ = hv_fetch((HV*) SHAREDSvGET(shared), ckey, len,0);
678 if(SvTYPE(hentry) == SVt_NULL) {
679 retval = &PL_sv_undef;
681 slot = (shared_sv*) SvIV(hentry);
682 if(SvROK(SHAREDSvGET(slot))) {
683 shared_sv* target = (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot)));
684 retval = shared_sv_attach_sv(NULL, target);
686 retval = newSVsv(SHAREDSvGET(slot));
690 retval = &PL_sv_undef;
692 SHAREDSvUNLOCK(shared);
701 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
704 SHAREDSvLOCK(shared);
705 Perl_hv_iterinit(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
706 entry = Perl_hv_iternext(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
708 slot = (shared_sv*) SvIV(Perl_hv_iterval(PL_sharedsv_space, (HV*) SHAREDSvGET(shared), entry));
709 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
710 entry = Perl_hv_iternext(PL_sharedsv_space,(HV*) SHAREDSvGET(shared));
712 SHAREDSvEDIT(shared);
713 hv_clear((HV*) SHAREDSvGET(shared));
714 SHAREDSvRELEASE(shared);
715 SHAREDSvUNLOCK(shared);
721 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
725 SHAREDSvLOCK(shared);
726 Perl_hv_iterinit(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
727 entry = Perl_hv_iternext(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
729 key = Perl_hv_iterkey(PL_sharedsv_space, entry,&len);
730 RETVAL = newSVpv(key, len);
732 RETVAL = &PL_sv_undef;
734 SHAREDSvUNLOCK(shared);
740 NEXTKEY(self, oldkey)
744 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
748 SHAREDSvLOCK(shared);
749 entry = Perl_hv_iternext(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
751 key = Perl_hv_iterkey(PL_sharedsv_space, entry,&len);
752 RETVAL = newSVpv(key, len);
754 RETVAL = &PL_sv_undef;
756 SHAREDSvUNLOCK(shared);
766 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
768 char* ckey = SvPV(key, len);
769 SHAREDSvLOCK(shared);
770 if(hv_exists((HV*)SHAREDSvGET(shared), ckey, len)) {
775 SHAREDSvUNLOCK(shared);
784 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
787 char* ckey = SvPV(key, len);
789 SHAREDSvLOCK(shared);
790 SHAREDSvEDIT(shared);
791 tmp = hv_delete((HV*) SHAREDSvGET(shared), ckey, len,0);
792 SHAREDSvRELEASE(shared);
794 slot = (shared_sv*) SvIV(tmp);
795 if(SvROK(SHAREDSvGET(slot))) {
796 shared_sv* target = (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot)));
797 RETVAL = shared_sv_attach_sv(NULL, target);
799 RETVAL = newSVsv(SHAREDSvGET(slot));
801 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
803 RETVAL = &PL_sv_undef;
805 SHAREDSvUNLOCK(shared);