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);
201 shared = Perl_sharedsv_find(aTHX, ref);
203 croak("unlock can only be used on shared values");
204 SHAREDSvUNLOCK(shared);
213 shared = Perl_sharedsv_find(aTHX, ref);
215 croak("lock can only be used on shared values");
216 SHAREDSvLOCK(shared);
220 cond_wait_enabled(ref)
227 shared = Perl_sharedsv_find(aTHX_ ref);
229 croak("cond_wait can only be used on shared values");
230 if(shared->owner != PERL_GET_CONTEXT)
231 croak("You need a lock before you can cond_wait");
232 MUTEX_LOCK(&shared->mutex);
233 shared->owner = NULL;
234 locks = shared->locks = 0;
235 COND_WAIT(&shared->user_cond, &shared->mutex);
236 shared->owner = PERL_GET_CONTEXT;
237 shared->locks = locks;
238 MUTEX_UNLOCK(&shared->mutex);
240 void cond_signal_enabled(ref)
246 shared = Perl_sharedsv_find(aTHX_ ref);
248 croak("cond_signal can only be used on shared values");
249 COND_SIGNAL(&shared->user_cond);
252 void cond_broadcast_enabled(ref)
258 shared = Perl_sharedsv_find(aTHX_ ref);
260 croak("cond_broadcast can only be used on shared values");
261 COND_BROADCAST(&shared->user_cond);
263 MODULE = threads::shared PACKAGE = threads::shared::sv
270 shared_sv* shared = Perl_sharedsv_new(aTHX);
272 SV* obj = newSViv((IV)shared);
273 SHAREDSvEDIT(shared);
274 SHAREDSvGET(shared) = newSVsv(value);
275 SHAREDSvRELEASE(shared);
276 sv_magic(value, 0, PERL_MAGIC_ext, "threads::shared", 16);
277 shared_magic = mg_find(value, PERL_MAGIC_ext);
278 shared_magic->mg_virtual = &svtable;
279 shared_magic->mg_obj = newSViv((IV)shared);
280 shared_magic->mg_flags |= MGf_REFCOUNTED;
281 shared_magic->mg_private = 0;
288 MODULE = threads::shared PACKAGE = threads::shared::av
295 shared_sv* shared = Perl_sharedsv_new(aTHX);
296 SV* obj = newSViv((IV)shared);
297 SHAREDSvEDIT(shared);
298 SHAREDSvGET(shared) = (SV*) newAV();
299 SHAREDSvRELEASE(shared);
305 STORE(self, index, value)
310 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
315 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(value));
317 Perl_croak(aTHX_ "You cannot assign a non shared reference to an shared array");
319 value = newRV_noinc(newSViv((IV)target));
321 SHAREDSvLOCK(shared);
322 aentry_ = av_fetch((AV*) SHAREDSvGET(shared), SvIV(index), 0);
323 if(aentry_ && SvIV((*aentry_))) {
325 slot = (shared_sv*) SvIV(aentry);
326 if(SvROK(SHAREDSvGET(slot)))
327 Perl_sharedsv_thrcnt_dec(aTHX_ (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot))));
329 sv_setsv(SHAREDSvGET(slot), value);
330 SHAREDSvRELEASE(slot);
332 slot = Perl_sharedsv_new(aTHX);
333 SHAREDSvEDIT(shared);
334 SHAREDSvGET(slot) = newSVsv(value);
335 aentry = newSViv((IV)slot);
336 av_store((AV*) SHAREDSvGET(shared), SvIV(index), aentry);
337 SHAREDSvRELEASE(shared);
339 if(SvROK(SHAREDSvGET(slot)))
340 Perl_sharedsv_thrcnt_inc(aTHX_ (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot))));
342 SHAREDSvUNLOCK(shared);
349 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
354 SHAREDSvLOCK(shared);
355 aentry_ = av_fetch((AV*) SHAREDSvGET(shared), SvIV(index),0);
358 if(SvTYPE(aentry) == SVt_NULL) {
359 retval = &PL_sv_undef;
361 slot = (shared_sv*) SvIV(aentry);
362 if(SvROK(SHAREDSvGET(slot))) {
363 shared_sv* target = (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot)));
364 retval = shared_sv_attach_sv(NULL,target);
366 retval = newSVsv(SHAREDSvGET(slot));
370 retval = &PL_sv_undef;
372 SHAREDSvUNLOCK(shared);
381 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
383 SHAREDSvLOCK(shared);
384 for(i = 1; i < items; i++) {
385 shared_sv* slot = Perl_sharedsv_new(aTHX);
388 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(tmp));
390 Perl_croak(aTHX_ "You cannot assign a non shared reference to an shared array");
392 tmp = newRV_noinc(newSViv((IV)target));
395 SHAREDSvGET(slot) = newSVsv(tmp);
396 av_push((AV*) SHAREDSvGET(shared), newSViv((IV)slot));
397 SHAREDSvRELEASE(slot);
398 if(SvROK(SHAREDSvGET(slot)))
399 Perl_sharedsv_thrcnt_inc(aTHX_ (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot))));
401 SHAREDSvUNLOCK(shared);
407 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
409 SHAREDSvLOCK(shared);
410 SHAREDSvEDIT(shared);
411 av_unshift((AV*)SHAREDSvGET(shared), items - 1);
412 SHAREDSvRELEASE(shared);
413 for(i = 1; i < items; i++) {
414 shared_sv* slot = Perl_sharedsv_new(aTHX);
417 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(tmp));
419 Perl_croak(aTHX_ "You cannot assign a non shared reference to an shared array");
421 tmp = newRV_noinc(newSViv((IV)target));
424 SHAREDSvGET(slot) = newSVsv(tmp);
425 av_store((AV*) SHAREDSvGET(shared), i - 1, newSViv((IV)slot));
426 SHAREDSvRELEASE(slot);
427 if(SvROK(SHAREDSvGET(slot)))
428 Perl_sharedsv_thrcnt_inc(aTHX_ (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot))));
430 SHAREDSvUNLOCK(shared);
436 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
439 SHAREDSvLOCK(shared);
440 SHAREDSvEDIT(shared);
441 retval = av_pop((AV*)SHAREDSvGET(shared));
442 SHAREDSvRELEASE(shared);
443 if(retval && SvIV(retval)) {
444 slot = (shared_sv*) SvIV(retval);
445 if(SvROK(SHAREDSvGET(slot))) {
446 shared_sv* target = (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot)));
447 retval = shared_sv_attach_sv(NULL,target);
449 retval = newSVsv(SHAREDSvGET(slot));
451 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
453 retval = &PL_sv_undef;
455 SHAREDSvUNLOCK(shared);
465 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
468 SHAREDSvLOCK(shared);
469 SHAREDSvEDIT(shared);
470 retval = av_shift((AV*)SHAREDSvGET(shared));
471 SHAREDSvRELEASE(shared);
472 if(retval && SvIV(retval)) {
473 slot = (shared_sv*) SvIV(retval);
474 if(SvROK(SHAREDSvGET(slot))) {
475 shared_sv* target = (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot)));
476 retval = shared_sv_attach_sv(NULL,target);
478 retval = newSVsv(SHAREDSvGET(slot));
480 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
482 retval = &PL_sv_undef;
484 SHAREDSvUNLOCK(shared);
493 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
497 SHAREDSvLOCK(shared);
498 svp = AvARRAY((AV*)SHAREDSvGET(shared));
499 i = AvFILLp((AV*)SHAREDSvGET(shared));
502 Perl_sharedsv_thrcnt_dec(aTHX_ (shared_sv*) SvIV(svp[i]));
506 SHAREDSvEDIT(shared);
507 av_clear((AV*)SHAREDSvGET(shared));
508 SHAREDSvRELEASE(shared);
509 SHAREDSvUNLOCK(shared);
516 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
517 SHAREDSvEDIT(shared);
518 av_extend((AV*)SHAREDSvGET(shared), (I32) SvIV(count));
519 SHAREDSvRELEASE(shared);
529 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
531 SHAREDSvLOCK(shared);
532 exists = av_exists((AV*) SHAREDSvGET(shared), (I32) SvIV(index));
538 SHAREDSvUNLOCK(shared);
541 STORESIZE(self,count)
545 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
546 SHAREDSvEDIT(shared);
547 av_fill((AV*) SHAREDSvGET(shared), (I32) SvIV(count));
548 SHAREDSvRELEASE(shared);
554 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
555 SHAREDSvLOCK(shared);
556 RETVAL = newSViv(av_len((AV*) SHAREDSvGET(shared)) + 1);
557 SHAREDSvUNLOCK(shared);
566 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
568 SHAREDSvLOCK(shared);
569 if(av_exists((AV*) SHAREDSvGET(shared), (I32) SvIV(index))) {
571 SHAREDSvEDIT(shared);
572 tmp = av_delete((AV*)SHAREDSvGET(shared), (I32) SvIV(index),0);
573 SHAREDSvRELEASE(shared);
575 slot = (shared_sv*) SvIV(tmp);
576 if(SvROK(SHAREDSvGET(slot))) {
577 shared_sv* target = (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot)));
578 RETVAL = shared_sv_attach_sv(NULL,target);
580 RETVAL = newSVsv(SHAREDSvGET(slot));
582 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
584 RETVAL = &PL_sv_undef;
587 RETVAL = &PL_sv_undef;
589 SHAREDSvUNLOCK(shared);
594 SPLICE(self, offset, length, ...)
599 croak("Splice is not implmented for shared arrays");
601 MODULE = threads::shared PACKAGE = threads::shared::hv
608 shared_sv* shared = Perl_sharedsv_new(aTHX);
609 SV* obj = newSViv((IV)shared);
610 SHAREDSvEDIT(shared);
611 SHAREDSvGET(shared) = (SV*) newHV();
612 SHAREDSvRELEASE(shared);
618 STORE(self, key, value)
623 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
628 char* ckey = SvPV(key, len);
629 SHAREDSvLOCK(shared);
631 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(value));
633 Perl_croak(aTHX_ "You cannot assign a non shared reference to a shared hash");
635 SHAREDSvEDIT(shared);
636 value = newRV_noinc(newSViv((IV)target));
637 SHAREDSvRELEASE(shared);
639 hentry_ = hv_fetch((HV*) SHAREDSvGET(shared), ckey, len, 0);
640 if(hentry_ && SvIV((*hentry_))) {
642 slot = (shared_sv*) SvIV(hentry);
643 if(SvROK(SHAREDSvGET(slot)))
644 Perl_sharedsv_thrcnt_dec(aTHX_ (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot))));
646 sv_setsv(SHAREDSvGET(slot), value);
647 SHAREDSvRELEASE(slot);
649 slot = Perl_sharedsv_new(aTHX);
650 SHAREDSvEDIT(shared);
651 SHAREDSvGET(slot) = newSVsv(value);
652 hentry = newSViv((IV)slot);
653 hv_store((HV*) SHAREDSvGET(shared), ckey,len , hentry, 0);
654 SHAREDSvRELEASE(shared);
656 if(SvROK(SHAREDSvGET(slot)))
657 Perl_sharedsv_thrcnt_inc(aTHX_ (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot))));
658 SHAREDSvUNLOCK(shared);
666 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
672 char* ckey = SvPV(key, len);
673 SHAREDSvLOCK(shared);
674 hentry_ = hv_fetch((HV*) SHAREDSvGET(shared), ckey, len,0);
677 if(SvTYPE(hentry) == SVt_NULL) {
678 retval = &PL_sv_undef;
680 slot = (shared_sv*) SvIV(hentry);
681 if(SvROK(SHAREDSvGET(slot))) {
682 shared_sv* target = (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot)));
683 retval = shared_sv_attach_sv(NULL, target);
685 retval = newSVsv(SHAREDSvGET(slot));
689 retval = &PL_sv_undef;
691 SHAREDSvUNLOCK(shared);
700 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
703 SHAREDSvLOCK(shared);
704 Perl_hv_iterinit(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
705 entry = Perl_hv_iternext(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
707 slot = (shared_sv*) SvIV(Perl_hv_iterval(PL_sharedsv_space, (HV*) SHAREDSvGET(shared), entry));
708 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
709 entry = Perl_hv_iternext(PL_sharedsv_space,(HV*) SHAREDSvGET(shared));
711 SHAREDSvEDIT(shared);
712 hv_clear((HV*) SHAREDSvGET(shared));
713 SHAREDSvRELEASE(shared);
714 SHAREDSvUNLOCK(shared);
720 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
724 SHAREDSvLOCK(shared);
725 Perl_hv_iterinit(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
726 entry = Perl_hv_iternext(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
728 key = Perl_hv_iterkey(PL_sharedsv_space, entry,&len);
729 RETVAL = newSVpv(key, len);
731 RETVAL = &PL_sv_undef;
733 SHAREDSvUNLOCK(shared);
739 NEXTKEY(self, oldkey)
743 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
747 SHAREDSvLOCK(shared);
748 entry = Perl_hv_iternext(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
750 key = Perl_hv_iterkey(PL_sharedsv_space, entry,&len);
751 RETVAL = newSVpv(key, len);
753 RETVAL = &PL_sv_undef;
755 SHAREDSvUNLOCK(shared);
765 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
767 char* ckey = SvPV(key, len);
768 SHAREDSvLOCK(shared);
769 if(hv_exists((HV*)SHAREDSvGET(shared), ckey, len)) {
774 SHAREDSvUNLOCK(shared);
783 shared_sv* shared = (shared_sv*) SvIV(SvRV(self));
786 char* ckey = SvPV(key, len);
788 SHAREDSvLOCK(shared);
789 SHAREDSvEDIT(shared);
790 tmp = hv_delete((HV*) SHAREDSvGET(shared), ckey, len,0);
791 SHAREDSvRELEASE(shared);
793 slot = (shared_sv*) SvIV(tmp);
794 if(SvROK(SHAREDSvGET(slot))) {
795 shared_sv* target = (shared_sv*) SvIV(SvRV(SHAREDSvGET(slot)));
796 RETVAL = shared_sv_attach_sv(NULL, target);
798 RETVAL = newSVsv(SHAREDSvGET(slot));
800 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
802 RETVAL = &PL_sv_undef;
804 SHAREDSvUNLOCK(shared);