3 * Copyright (c) 2001, Larry Wall
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
11 * Contributed by Arthur Bergman arthur@contiller.se
13 * "Hand any two wizards a piece of rope and they would instinctively pull in
14 * opposite directions."
19 #define PERL_NO_GET_CONTEXT
24 PerlInterpreter *PL_sharedsv_space; /* The shared sv space */
25 perl_mutex PL_sharedsv_space_mutex; /* Mutex protecting the shared sv space */
28 SV *sv; /* The actual SV */
29 perl_mutex mutex; /* Our mutex */
30 perl_cond cond; /* Our condition variable */
31 perl_cond user_cond; /* For user-level conditions */
32 IV locks; /* Number of locks held */
33 PerlInterpreter *owner; /* Who owns the lock? */
34 U16 index; /* Update index */
37 #define SHAREDSvGET(a) (a->sv)
38 #define SHAREDSvLOCK(a) Perl_sharedsv_lock(aTHX_ a)
39 #define SHAREDSvUNLOCK(a) Perl_sharedsv_unlock(aTHX_ a)
41 #define SHAREDSvEDIT(a) STMT_START { \
42 MUTEX_LOCK(&PL_sharedsv_space_mutex); \
44 PERL_SET_CONTEXT(PL_sharedsv_space); \
47 #define SHAREDSvRELEASE(a) STMT_START { \
48 PERL_SET_CONTEXT((a)->owner); \
49 SHAREDSvUNLOCK((a)); \
50 MUTEX_UNLOCK(&PL_sharedsv_space_mutex); \
53 extern void Perl_sharedsv_init(pTHX);
54 extern shared_sv* Perl_sharedsv_new(pTHX);
55 extern shared_sv* Perl_sharedsv_find(pTHX_ SV* sv);
56 extern void Perl_sharedsv_lock(pTHX_ shared_sv* ssv);
57 extern void Perl_sharedsv_unlock(pTHX_ shared_sv* ssv);
58 extern void Perl_sharedsv_unlock_scope(pTHX_ shared_sv* ssv);
59 extern void Perl_sharedsv_thrcnt_inc(pTHX_ shared_sv* ssv);
60 extern void Perl_sharedsv_thrcnt_dec(pTHX_ shared_sv* ssv);
65 Shared SV is a structure for keeping the backend storage
72 =head1 Shared SV Functions
74 =for apidoc sharedsv_init
76 Saves a space for keeping SVs wider than an interpreter,
77 currently only stores a pointer to the first interpreter.
84 Perl_sharedsv_init(pTHX)
86 PerlInterpreter* old_context = PERL_GET_CONTEXT;
87 PL_sharedsv_space = perl_alloc();
88 perl_construct(PL_sharedsv_space);
89 PERL_SET_CONTEXT(old_context);
90 MUTEX_INIT(&PL_sharedsv_space_mutex);
94 =for apidoc sharedsv_new
96 Allocates a new shared sv struct, you must yourself create the SV/AV/HV.
101 Perl_sharedsv_new(pTHX)
104 New(2555,ssv,1,shared_sv);
105 MUTEX_INIT(&ssv->mutex);
106 COND_INIT(&ssv->cond);
107 COND_INIT(&ssv->user_cond);
116 =for apidoc sharedsv_find
118 Tries to find if a given SV has a shared backend, either by
119 looking at magic, or by checking if it is tied again threads::shared.
125 Perl_sharedsv_find(pTHX_ SV* sv)
127 /* does all it can to find a shared_sv struct, returns NULL otherwise */
128 shared_sv* ssv = NULL;
129 switch (SvTYPE(sv)) {
133 MAGIC* mg = mg_find(sv, PERL_MAGIC_ext);
135 if(strcmp(mg->mg_ptr,"threads::shared"))
137 ssv = INT2PTR(shared_sv *, SvIV(mg->mg_obj));
141 mg = mg_find(sv,PERL_MAGIC_tied);
143 SV* obj = SvTIED_obj(sv,mg);
144 if(sv_derived_from(obj, "threads::shared"))
145 ssv = INT2PTR(shared_sv *, SvIV(SvRV(obj)));
154 =for apidoc sharedsv_lock
156 Recursive locks on a sharedsv.
157 Locks are dynamically scoped at the level of the first lock.
161 Perl_sharedsv_lock(pTHX_ shared_sv* ssv)
165 MUTEX_LOCK(&ssv->mutex);
166 if(ssv->owner && ssv->owner == my_perl) {
168 MUTEX_UNLOCK(&ssv->mutex);
172 COND_WAIT(&ssv->cond,&ssv->mutex);
174 ssv->owner = my_perl;
176 SAVEDESTRUCTOR_X(Perl_sharedsv_unlock_scope,ssv);
177 MUTEX_UNLOCK(&ssv->mutex);
181 =for apidoc sharedsv_unlock
183 Recursively unlocks a shared sv.
189 Perl_sharedsv_unlock(pTHX_ shared_sv* ssv)
191 MUTEX_LOCK(&ssv->mutex);
192 if(ssv->owner != my_perl) {
193 Perl_croak(aTHX_ "panic: Perl_sharedsv_unlock unlocking mutex that we don't own");
194 MUTEX_UNLOCK(&ssv->mutex);
198 if(--ssv->locks == 0) {
200 COND_SIGNAL(&ssv->cond);
202 MUTEX_UNLOCK(&ssv->mutex);
206 Perl_sharedsv_unlock_scope(pTHX_ shared_sv* ssv)
208 MUTEX_LOCK(&ssv->mutex);
209 if(ssv->owner != my_perl) {
210 MUTEX_UNLOCK(&ssv->mutex);
215 COND_SIGNAL(&ssv->cond);
216 MUTEX_UNLOCK(&ssv->mutex);
220 =for apidoc sharedsv_thrcnt_inc
222 Increments the threadcount of a sharedsv.
226 Perl_sharedsv_thrcnt_inc(pTHX_ shared_sv* ssv)
229 SvREFCNT_inc(ssv->sv);
234 =for apidoc sharedsv_thrcnt_dec
236 Decrements the threadcount of a shared sv. When a threads frontend is freed
237 this function should be called.
243 Perl_sharedsv_thrcnt_dec(pTHX_ shared_sv* ssv)
247 sv = SHAREDSvGET(ssv);
248 if (SvREFCNT(sv) == 1) {
249 switch (SvTYPE(sv)) {
252 Perl_sharedsv_thrcnt_dec(aTHX_ INT2PTR(shared_sv *, SvIV(SvRV(sv))));
255 SV **src_ary = AvARRAY((AV *)sv);
256 SSize_t items = AvFILLp((AV *)sv) + 1;
258 while (items-- > 0) {
260 Perl_sharedsv_thrcnt_dec(aTHX_ INT2PTR(shared_sv *, SvIV(*src_ary)));
267 (void)hv_iterinit((HV *)sv);
268 while ((entry = hv_iternext((HV *)sv)))
269 Perl_sharedsv_thrcnt_dec(
270 aTHX_ INT2PTR(shared_sv *, SvIV(hv_iterval((HV *)sv, entry)))
276 Perl_sv_free(PL_sharedsv_space,SHAREDSvGET(ssv));
283 #define shared_sv_attach_sv(sv,shared) Perl_shared_sv_attach_sv(aTHX_ sv,shared)
285 SV* Perl_shared_sv_attach_sv (pTHX_ SV* sv, shared_sv* shared) {
286 HV* shared_hv = get_hv("threads::shared::shared", FALSE);
287 SV* id = newSViv(PTR2IV(shared));
288 STRLEN length = sv_len(id);
290 SV** tiedobject_ = hv_fetch(shared_hv, SvPV(id,length), length, 0);
292 tiedobject = (*tiedobject_);
295 SvRV(sv) = SvRV(tiedobject);
297 sv = newRV(SvRV(tiedobject));
300 switch(SvTYPE(SHAREDSvGET(shared))) {
303 SV* obj_ref = newSViv(0);
304 SV* obj = newSVrv(obj_ref,"threads::shared::av");
306 sv_setiv(obj,PTR2IV(shared));
307 weakref = newRV((SV*)hv);
308 sv = newRV_noinc((SV*)hv);
309 sv_rvweaken(weakref);
310 sv_magic((SV*) hv, obj_ref, PERL_MAGIC_tied, Nullch, 0);
311 hv_store(shared_hv, SvPV(id,length), length, weakref, 0);
312 Perl_sharedsv_thrcnt_inc(aTHX_ shared);
317 SV* obj_ref = newSViv(0);
318 SV* obj = newSVrv(obj_ref,"threads::shared::hv");
320 sv_setiv(obj,PTR2IV(shared));
321 weakref = newRV((SV*)hv);
322 sv = newRV_noinc((SV*)hv);
323 sv_rvweaken(weakref);
324 sv_magic((SV*) hv, obj_ref, PERL_MAGIC_tied, Nullch, 0);
325 hv_store(shared_hv, SvPV(id,length), length, weakref, 0);
326 Perl_sharedsv_thrcnt_inc(aTHX_ shared);
331 SV* value = newSVsv(SHAREDSvGET(shared));
332 SV* obj = newSViv(PTR2IV(shared));
333 sv_magic(value, 0, PERL_MAGIC_ext, "threads::shared", 16);
334 shared_magic = mg_find(value, PERL_MAGIC_ext);
335 shared_magic->mg_virtual = &svtable;
336 shared_magic->mg_obj = newSViv(PTR2IV(shared));
337 shared_magic->mg_flags |= MGf_REFCOUNTED;
338 shared_magic->mg_private = 0;
340 sv = newRV_noinc(value);
341 value = newRV(value);
343 hv_store(shared_hv, SvPV(id,length),length, value, 0);
344 Perl_sharedsv_thrcnt_inc(aTHX_ shared);
353 int shared_sv_fetch_mg (pTHX_ SV* sv, MAGIC *mg) {
354 shared_sv* shared = INT2PTR(shared_sv*, SvIV(mg->mg_obj));
355 SHAREDSvLOCK(shared);
356 if(mg->mg_private != shared->index) {
357 if(SvROK(SHAREDSvGET(shared))) {
358 shared_sv* target = INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(shared))));
359 shared_sv_attach_sv(sv, target);
361 sv_setsv(sv, SHAREDSvGET(shared));
363 mg->mg_private = shared->index;
365 SHAREDSvUNLOCK(shared);
370 int shared_sv_store_mg (pTHX_ SV* sv, MAGIC *mg) {
371 shared_sv* shared = INT2PTR(shared_sv*, SvIV(mg->mg_obj));
372 SHAREDSvLOCK(shared);
373 if(SvROK(SHAREDSvGET(shared)))
374 Perl_sharedsv_thrcnt_dec(aTHX_ INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(shared)))));
376 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(sv));
378 sv_setsv(sv,SHAREDSvGET(shared));
379 SHAREDSvUNLOCK(shared);
380 Perl_croak(aTHX_ "You cannot assign a non shared reference to a shared scalar");
382 SHAREDSvEDIT(shared);
383 Perl_sv_free(PL_sharedsv_space,SHAREDSvGET(shared));
384 SHAREDSvGET(shared) = newRV_noinc(newSViv(PTR2IV(target)));
386 SHAREDSvEDIT(shared);
387 sv_setsv(SHAREDSvGET(shared), sv);
390 mg->mg_private = shared->index;
391 SHAREDSvRELEASE(shared);
392 if(SvROK(SHAREDSvGET(shared)))
393 Perl_sharedsv_thrcnt_inc(aTHX_ INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(shared)))));
394 SHAREDSvUNLOCK(shared);
399 shared_sv_destroy_mg (pTHX_ SV* sv, MAGIC *mg)
401 shared_sv* shared = INT2PTR(shared_sv*, SvIV(mg->mg_obj));
403 HV* shared_hv = get_hv("threads::shared::shared", FALSE);
404 SV* id = newSViv(PTR2IV(shared));
405 STRLEN length = sv_len(id);
406 hv_delete(shared_hv, SvPV(id,length), length,0);
407 Perl_sharedsv_thrcnt_dec(aTHX_ shared);
412 MGVTBL svtable = {MEMBER_TO_FPTR(shared_sv_fetch_mg),
413 MEMBER_TO_FPTR(shared_sv_store_mg),
416 MEMBER_TO_FPTR(shared_sv_destroy_mg)
419 MODULE = threads::shared PACKAGE = threads::shared
429 RETVAL = newSViv(SvIV(SvRV(ref)));
441 shared = Perl_sharedsv_find(aTHX, ref);
443 croak("thrcnt can only be used on shared values");
444 SHAREDSvLOCK(shared);
445 RETVAL = newSViv(SvREFCNT(SHAREDSvGET(shared)));
446 SHAREDSvUNLOCK(shared);
457 PerlInterpreter* origperl = INT2PTR(PerlInterpreter*, SvIV(perl));
458 PerlInterpreter* oldperl = PERL_GET_CONTEXT;
461 shared = Perl_sharedsv_find(aTHX, ref);
463 croak("thrcnt can only be used on shared values");
464 PERL_SET_CONTEXT(origperl);
465 Perl_sharedsv_thrcnt_inc(aTHX_ shared);
466 PERL_SET_CONTEXT(oldperl);
472 shared_sv* shared = INT2PTR(shared_sv*, SvIV(ref));
474 croak("thrcnt can only be used on shared values");
475 Perl_sharedsv_thrcnt_dec(aTHX_ shared);
485 shared = Perl_sharedsv_find(aTHX, ref);
487 croak("unlock can only be used on shared values");
488 SHAREDSvUNLOCK(shared);
497 shared = Perl_sharedsv_find(aTHX, ref);
499 croak("lock can only be used on shared values");
500 SHAREDSvLOCK(shared);
504 cond_wait_enabled(ref)
512 shared = Perl_sharedsv_find(aTHX_ ref);
514 croak("cond_wait can only be used on shared values");
515 if(shared->owner != PERL_GET_CONTEXT)
516 croak("You need a lock before you can cond_wait");
517 MUTEX_LOCK(&shared->mutex);
518 shared->owner = NULL;
519 locks = shared->locks = 0;
520 COND_WAIT(&shared->user_cond, &shared->mutex);
521 shared->owner = PERL_GET_CONTEXT;
522 shared->locks = locks;
523 MUTEX_UNLOCK(&shared->mutex);
525 void cond_signal_enabled(ref)
532 shared = Perl_sharedsv_find(aTHX_ ref);
534 croak("cond_signal can only be used on shared values");
535 COND_SIGNAL(&shared->user_cond);
538 void cond_broadcast_enabled(ref)
545 shared = Perl_sharedsv_find(aTHX_ ref);
547 croak("cond_broadcast can only be used on shared values");
548 COND_BROADCAST(&shared->user_cond);
550 MODULE = threads::shared PACKAGE = threads::shared::sv
557 shared_sv* shared = Perl_sharedsv_new(aTHX);
559 SV* obj = newSViv(PTR2IV(shared));
560 SHAREDSvEDIT(shared);
561 SHAREDSvGET(shared) = newSVsv(value);
562 SHAREDSvRELEASE(shared);
563 sv_magic(value, 0, PERL_MAGIC_ext, "threads::shared", 16);
564 shared_magic = mg_find(value, PERL_MAGIC_ext);
565 shared_magic->mg_virtual = &svtable;
566 shared_magic->mg_obj = newSViv(PTR2IV(shared));
567 shared_magic->mg_flags |= MGf_REFCOUNTED;
568 shared_magic->mg_private = 0;
575 MODULE = threads::shared PACKAGE = threads::shared::av
582 shared_sv* shared = Perl_sharedsv_new(aTHX);
583 SV* obj = newSViv(PTR2IV(shared));
584 SHAREDSvEDIT(shared);
585 SHAREDSvGET(shared) = (SV*) newAV();
586 SHAREDSvRELEASE(shared);
592 STORE(self, index, value)
597 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
602 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(value));
604 Perl_croak(aTHX_ "You cannot assign a non shared reference to a shared array");
606 value = newRV_noinc(newSViv(PTR2IV(target)));
608 SHAREDSvLOCK(shared);
609 aentry_ = av_fetch((AV*) SHAREDSvGET(shared), SvIV(index), 0);
610 if(aentry_ && SvIV((*aentry_))) {
612 slot = INT2PTR(shared_sv*, SvIV(aentry));
613 if(SvROK(SHAREDSvGET(slot)))
614 Perl_sharedsv_thrcnt_dec(aTHX_ INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot)))));
616 sv_setsv(SHAREDSvGET(slot), value);
617 SHAREDSvRELEASE(slot);
619 slot = Perl_sharedsv_new(aTHX);
620 SHAREDSvEDIT(shared);
621 SHAREDSvGET(slot) = newSVsv(value);
622 aentry = newSViv(PTR2IV(slot));
623 av_store((AV*) SHAREDSvGET(shared), SvIV(index), aentry);
624 SHAREDSvRELEASE(shared);
626 if(SvROK(SHAREDSvGET(slot)))
627 Perl_sharedsv_thrcnt_inc(aTHX_ INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot)))));
629 SHAREDSvUNLOCK(shared);
636 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
641 SHAREDSvLOCK(shared);
642 aentry_ = av_fetch((AV*) SHAREDSvGET(shared), SvIV(index),0);
645 if(SvTYPE(aentry) == SVt_NULL) {
646 retval = &PL_sv_undef;
648 slot = INT2PTR(shared_sv*, SvIV(aentry));
649 if(SvROK(SHAREDSvGET(slot))) {
650 shared_sv* target = INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot))));
651 retval = Perl_shared_sv_attach_sv(aTHX_ NULL,target);
653 retval = newSVsv(SHAREDSvGET(slot));
657 retval = &PL_sv_undef;
659 SHAREDSvUNLOCK(shared);
668 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
670 SHAREDSvLOCK(shared);
671 for(i = 1; i < items; i++) {
672 shared_sv* slot = Perl_sharedsv_new(aTHX);
675 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(tmp));
677 Perl_croak(aTHX_ "You cannot assign a non shared reference to a shared array");
679 tmp = newRV_noinc(newSViv(PTR2IV(target)));
682 SHAREDSvGET(slot) = newSVsv(tmp);
683 av_push((AV*) SHAREDSvGET(shared), newSViv(PTR2IV(slot)));
684 SHAREDSvRELEASE(slot);
685 if(SvROK(SHAREDSvGET(slot)))
686 Perl_sharedsv_thrcnt_inc(aTHX_ INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot)))));
688 SHAREDSvUNLOCK(shared);
694 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
696 SHAREDSvLOCK(shared);
697 SHAREDSvEDIT(shared);
698 av_unshift((AV*)SHAREDSvGET(shared), items - 1);
699 SHAREDSvRELEASE(shared);
700 for(i = 1; i < items; i++) {
701 shared_sv* slot = Perl_sharedsv_new(aTHX);
704 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(tmp));
706 Perl_croak(aTHX_ "You cannot assign a non shared reference to a shared array");
708 tmp = newRV_noinc(newSViv(PTR2IV(target)));
711 SHAREDSvGET(slot) = newSVsv(tmp);
712 av_store((AV*) SHAREDSvGET(shared), i - 1, newSViv(PTR2IV(slot)));
713 SHAREDSvRELEASE(slot);
714 if(SvROK(SHAREDSvGET(slot)))
715 Perl_sharedsv_thrcnt_inc(aTHX_ INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot)))));
717 SHAREDSvUNLOCK(shared);
723 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
726 SHAREDSvLOCK(shared);
727 SHAREDSvEDIT(shared);
728 retval = av_pop((AV*)SHAREDSvGET(shared));
729 SHAREDSvRELEASE(shared);
730 if(retval && SvIV(retval)) {
731 slot = INT2PTR(shared_sv*, SvIV(retval));
732 if(SvROK(SHAREDSvGET(slot))) {
733 shared_sv* target = INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot))));
734 retval = Perl_shared_sv_attach_sv(aTHX_ NULL,target);
736 retval = newSVsv(SHAREDSvGET(slot));
738 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
740 retval = &PL_sv_undef;
742 SHAREDSvUNLOCK(shared);
752 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
755 SHAREDSvLOCK(shared);
756 SHAREDSvEDIT(shared);
757 retval = av_shift((AV*)SHAREDSvGET(shared));
758 SHAREDSvRELEASE(shared);
759 if(retval && SvIV(retval)) {
760 slot = INT2PTR(shared_sv*, SvIV(retval));
761 if(SvROK(SHAREDSvGET(slot))) {
762 shared_sv* target = INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot))));
763 retval = Perl_shared_sv_attach_sv(aTHX_ NULL,target);
765 retval = newSVsv(SHAREDSvGET(slot));
767 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
769 retval = &PL_sv_undef;
771 SHAREDSvUNLOCK(shared);
780 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
784 SHAREDSvLOCK(shared);
785 svp = AvARRAY((AV*)SHAREDSvGET(shared));
786 i = AvFILLp((AV*)SHAREDSvGET(shared));
789 Perl_sharedsv_thrcnt_dec(aTHX_ INT2PTR(shared_sv*, SvIV(svp[i])));
793 SHAREDSvEDIT(shared);
794 av_clear((AV*)SHAREDSvGET(shared));
795 SHAREDSvRELEASE(shared);
796 SHAREDSvUNLOCK(shared);
803 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
804 SHAREDSvEDIT(shared);
805 av_extend((AV*)SHAREDSvGET(shared), (I32) SvIV(count));
806 SHAREDSvRELEASE(shared);
816 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
818 SHAREDSvLOCK(shared);
819 exists = av_exists((AV*) SHAREDSvGET(shared), (I32) SvIV(index));
825 SHAREDSvUNLOCK(shared);
828 STORESIZE(self,count)
832 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
833 SHAREDSvEDIT(shared);
834 av_fill((AV*) SHAREDSvGET(shared), (I32) SvIV(count));
835 SHAREDSvRELEASE(shared);
841 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
842 SHAREDSvLOCK(shared);
843 RETVAL = newSViv(av_len((AV*) SHAREDSvGET(shared)) + 1);
844 SHAREDSvUNLOCK(shared);
853 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
855 SHAREDSvLOCK(shared);
856 if(av_exists((AV*) SHAREDSvGET(shared), (I32) SvIV(index))) {
858 SHAREDSvEDIT(shared);
859 tmp = av_delete((AV*)SHAREDSvGET(shared), (I32) SvIV(index),0);
860 SHAREDSvRELEASE(shared);
862 slot = INT2PTR(shared_sv*, SvIV(tmp));
863 if(SvROK(SHAREDSvGET(slot))) {
864 shared_sv* target = INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot))));
865 RETVAL = Perl_shared_sv_attach_sv(aTHX_ NULL,target);
867 RETVAL = newSVsv(SHAREDSvGET(slot));
869 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
871 RETVAL = &PL_sv_undef;
874 RETVAL = &PL_sv_undef;
876 SHAREDSvUNLOCK(shared);
881 SPLICE(self, offset, length, ...)
886 croak("Splice is not implmented for shared arrays");
888 MODULE = threads::shared PACKAGE = threads::shared::hv
895 shared_sv* shared = Perl_sharedsv_new(aTHX);
896 SV* obj = newSViv(PTR2IV(shared));
897 SHAREDSvEDIT(shared);
898 SHAREDSvGET(shared) = (SV*) newHV();
899 SHAREDSvRELEASE(shared);
905 STORE(self, key, value)
910 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
915 char* ckey = SvPV(key, len);
916 SHAREDSvLOCK(shared);
918 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(value));
920 Perl_croak(aTHX_ "You cannot assign a non shared reference to a shared hash");
922 SHAREDSvEDIT(shared);
923 value = newRV_noinc(newSViv(PTR2IV(target)));
924 SHAREDSvRELEASE(shared);
926 hentry_ = hv_fetch((HV*) SHAREDSvGET(shared), ckey, len, 0);
927 if(hentry_ && SvIV((*hentry_))) {
929 slot = INT2PTR(shared_sv*, SvIV(hentry));
930 if(SvROK(SHAREDSvGET(slot)))
931 Perl_sharedsv_thrcnt_dec(aTHX_ INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot)))));
933 sv_setsv(SHAREDSvGET(slot), value);
934 SHAREDSvRELEASE(slot);
936 slot = Perl_sharedsv_new(aTHX);
937 SHAREDSvEDIT(shared);
938 SHAREDSvGET(slot) = newSVsv(value);
939 hentry = newSViv(PTR2IV(slot));
940 hv_store((HV*) SHAREDSvGET(shared), ckey,len , hentry, 0);
941 SHAREDSvRELEASE(shared);
943 if(SvROK(SHAREDSvGET(slot)))
944 Perl_sharedsv_thrcnt_inc(aTHX_ INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot)))));
945 SHAREDSvUNLOCK(shared);
953 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
959 char* ckey = SvPV(key, len);
960 SHAREDSvLOCK(shared);
961 hentry_ = hv_fetch((HV*) SHAREDSvGET(shared), ckey, len,0);
964 if(SvTYPE(hentry) == SVt_NULL) {
965 retval = &PL_sv_undef;
967 slot = INT2PTR(shared_sv*, SvIV(hentry));
968 if(SvROK(SHAREDSvGET(slot))) {
969 shared_sv* target = INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot))));
970 retval = Perl_shared_sv_attach_sv(aTHX_ NULL, target);
972 retval = newSVsv(SHAREDSvGET(slot));
976 retval = &PL_sv_undef;
978 SHAREDSvUNLOCK(shared);
987 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
990 SHAREDSvLOCK(shared);
991 Perl_hv_iterinit(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
992 entry = Perl_hv_iternext(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
994 slot = INT2PTR(shared_sv*, SvIV(Perl_hv_iterval(PL_sharedsv_space, (HV*) SHAREDSvGET(shared), entry)));
995 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
996 entry = Perl_hv_iternext(PL_sharedsv_space,(HV*) SHAREDSvGET(shared));
998 SHAREDSvEDIT(shared);
999 hv_clear((HV*) SHAREDSvGET(shared));
1000 SHAREDSvRELEASE(shared);
1001 SHAREDSvUNLOCK(shared);
1007 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
1011 SHAREDSvLOCK(shared);
1012 Perl_hv_iterinit(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
1013 entry = Perl_hv_iternext(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
1015 key = Perl_hv_iterkey(PL_sharedsv_space, entry,&len);
1016 RETVAL = newSVpv(key, len);
1018 RETVAL = &PL_sv_undef;
1020 SHAREDSvUNLOCK(shared);
1026 NEXTKEY(self, oldkey)
1030 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
1034 SHAREDSvLOCK(shared);
1035 entry = Perl_hv_iternext(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
1037 key = Perl_hv_iterkey(PL_sharedsv_space, entry,&len);
1038 RETVAL = newSVpv(key, len);
1040 RETVAL = &PL_sv_undef;
1042 SHAREDSvUNLOCK(shared);
1052 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
1054 char* ckey = SvPV(key, len);
1055 SHAREDSvLOCK(shared);
1056 if(hv_exists((HV*)SHAREDSvGET(shared), ckey, len)) {
1057 RETVAL = &PL_sv_yes;
1061 SHAREDSvUNLOCK(shared);
1070 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
1073 char* ckey = SvPV(key, len);
1075 SHAREDSvLOCK(shared);
1076 SHAREDSvEDIT(shared);
1077 tmp = hv_delete((HV*) SHAREDSvGET(shared), ckey, len,0);
1078 SHAREDSvRELEASE(shared);
1080 slot = INT2PTR(shared_sv*, SvIV(tmp));
1081 if(SvROK(SHAREDSvGET(slot))) {
1082 shared_sv* target = INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot))));
1083 RETVAL = Perl_shared_sv_attach_sv(aTHX_ NULL, target);
1085 RETVAL = newSVsv(SHAREDSvGET(slot));
1087 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
1089 RETVAL = &PL_sv_undef;
1091 SHAREDSvUNLOCK(shared);
1097 Perl_sharedsv_init(aTHX);