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 SV* Perl_shared_sv_attach_sv (pTHX_ SV* sv, shared_sv* shared) {
284 HV* shared_hv = get_hv("threads::shared::shared", FALSE);
285 SV* id = newSViv(PTR2IV(shared));
286 STRLEN length = sv_len(id);
288 SV** tiedobject_ = hv_fetch(shared_hv, SvPV(id,length), length, 0);
290 tiedobject = (*tiedobject_);
293 SvRV(sv) = SvRV(tiedobject);
295 sv = newRV(SvRV(tiedobject));
298 switch(SvTYPE(SHAREDSvGET(shared))) {
301 SV* obj_ref = newSViv(0);
302 SV* obj = newSVrv(obj_ref,"threads::shared::av");
304 sv_setiv(obj,PTR2IV(shared));
305 weakref = newRV((SV*)hv);
306 sv = newRV_noinc((SV*)hv);
307 sv_rvweaken(weakref);
308 sv_magic((SV*) hv, obj_ref, PERL_MAGIC_tied, Nullch, 0);
309 hv_store(shared_hv, SvPV(id,length), length, weakref, 0);
310 Perl_sharedsv_thrcnt_inc(aTHX_ shared);
315 SV* obj_ref = newSViv(0);
316 SV* obj = newSVrv(obj_ref,"threads::shared::hv");
318 sv_setiv(obj,PTR2IV(shared));
319 weakref = newRV((SV*)hv);
320 sv = newRV_noinc((SV*)hv);
321 sv_rvweaken(weakref);
322 sv_magic((SV*) hv, obj_ref, PERL_MAGIC_tied, Nullch, 0);
323 hv_store(shared_hv, SvPV(id,length), length, weakref, 0);
324 Perl_sharedsv_thrcnt_inc(aTHX_ shared);
329 SV* value = newSVsv(SHAREDSvGET(shared));
330 SV* obj = newSViv(PTR2IV(shared));
331 sv_magic(value, 0, PERL_MAGIC_ext, "threads::shared", 16);
332 shared_magic = mg_find(value, PERL_MAGIC_ext);
333 shared_magic->mg_virtual = &svtable;
334 shared_magic->mg_obj = newSViv(PTR2IV(shared));
335 shared_magic->mg_flags |= MGf_REFCOUNTED;
336 shared_magic->mg_private = 0;
338 sv = newRV_noinc(value);
339 value = newRV(value);
341 hv_store(shared_hv, SvPV(id,length),length, value, 0);
342 Perl_sharedsv_thrcnt_inc(aTHX_ shared);
351 int shared_sv_fetch_mg (pTHX_ SV* sv, MAGIC *mg) {
352 shared_sv* shared = INT2PTR(shared_sv*, SvIV(mg->mg_obj));
353 SHAREDSvLOCK(shared);
354 if(mg->mg_private != shared->index) {
355 if(SvROK(SHAREDSvGET(shared))) {
356 shared_sv* target = INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(shared))));
357 shared_sv_attach_sv(sv, target);
359 sv_setsv(sv, SHAREDSvGET(shared));
361 mg->mg_private = shared->index;
363 SHAREDSvUNLOCK(shared);
368 int shared_sv_store_mg (pTHX_ SV* sv, MAGIC *mg) {
369 shared_sv* shared = INT2PTR(shared_sv*, SvIV(mg->mg_obj));
370 SHAREDSvLOCK(shared);
371 if(SvROK(SHAREDSvGET(shared)))
372 Perl_sharedsv_thrcnt_dec(aTHX_ INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(shared)))));
374 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(sv));
376 sv_setsv(sv,SHAREDSvGET(shared));
377 SHAREDSvUNLOCK(shared);
378 Perl_croak(aTHX_ "You cannot assign a non shared reference to a shared scalar");
380 SHAREDSvEDIT(shared);
381 Perl_sv_free(PL_sharedsv_space,SHAREDSvGET(shared));
382 SHAREDSvGET(shared) = newRV_noinc(newSViv(PTR2IV(target)));
384 SHAREDSvEDIT(shared);
385 sv_setsv(SHAREDSvGET(shared), sv);
388 mg->mg_private = shared->index;
389 SHAREDSvRELEASE(shared);
390 if(SvROK(SHAREDSvGET(shared)))
391 Perl_sharedsv_thrcnt_inc(aTHX_ INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(shared)))));
392 SHAREDSvUNLOCK(shared);
396 int shared_sv_destroy_mg (pTHX_ SV* sv, MAGIC *mg) {
397 shared_sv* shared = INT2PTR(shared_sv*, SvIV(mg->mg_obj));
401 HV* shared_hv = get_hv("threads::shared::shared", FALSE);
402 SV* id = newSViv(PTR2IV(shared));
403 STRLEN length = sv_len(id);
404 hv_delete(shared_hv, SvPV(id,length), length,0);
406 Perl_sharedsv_thrcnt_dec(aTHX_ shared);
409 MGVTBL svtable = {MEMBER_TO_FPTR(shared_sv_fetch_mg),
410 MEMBER_TO_FPTR(shared_sv_store_mg),
413 MEMBER_TO_FPTR(shared_sv_destroy_mg)
416 MODULE = threads::shared PACKAGE = threads::shared
426 RETVAL = newSViv(SvIV(SvRV(ref)));
438 shared = Perl_sharedsv_find(aTHX, ref);
440 croak("thrcnt can only be used on shared values");
441 SHAREDSvLOCK(shared);
442 RETVAL = newSViv(SvREFCNT(SHAREDSvGET(shared)));
443 SHAREDSvUNLOCK(shared);
454 PerlInterpreter* origperl = INT2PTR(PerlInterpreter*, SvIV(perl));
455 PerlInterpreter* oldperl = PERL_GET_CONTEXT;
458 shared = Perl_sharedsv_find(aTHX, ref);
460 croak("thrcnt can only be used on shared values");
461 PERL_SET_CONTEXT(origperl);
462 Perl_sharedsv_thrcnt_inc(aTHX_ shared);
463 PERL_SET_CONTEXT(oldperl);
469 shared_sv* shared = INT2PTR(shared_sv*, SvIV(ref));
471 croak("thrcnt can only be used on shared values");
472 Perl_sharedsv_thrcnt_dec(aTHX_ shared);
482 shared = Perl_sharedsv_find(aTHX, ref);
484 croak("unlock can only be used on shared values");
485 SHAREDSvUNLOCK(shared);
494 shared = Perl_sharedsv_find(aTHX, ref);
496 croak("lock can only be used on shared values");
497 SHAREDSvLOCK(shared);
501 cond_wait_enabled(ref)
509 shared = Perl_sharedsv_find(aTHX_ ref);
511 croak("cond_wait can only be used on shared values");
512 if(shared->owner != PERL_GET_CONTEXT)
513 croak("You need a lock before you can cond_wait");
514 MUTEX_LOCK(&shared->mutex);
515 shared->owner = NULL;
516 locks = shared->locks = 0;
517 COND_WAIT(&shared->user_cond, &shared->mutex);
518 shared->owner = PERL_GET_CONTEXT;
519 shared->locks = locks;
520 MUTEX_UNLOCK(&shared->mutex);
522 void cond_signal_enabled(ref)
529 shared = Perl_sharedsv_find(aTHX_ ref);
531 croak("cond_signal can only be used on shared values");
532 COND_SIGNAL(&shared->user_cond);
535 void cond_broadcast_enabled(ref)
542 shared = Perl_sharedsv_find(aTHX_ ref);
544 croak("cond_broadcast can only be used on shared values");
545 COND_BROADCAST(&shared->user_cond);
547 MODULE = threads::shared PACKAGE = threads::shared::sv
554 shared_sv* shared = Perl_sharedsv_new(aTHX);
556 SV* obj = newSViv(PTR2IV(shared));
557 SHAREDSvEDIT(shared);
558 SHAREDSvGET(shared) = newSVsv(value);
559 SHAREDSvRELEASE(shared);
560 sv_magic(value, 0, PERL_MAGIC_ext, "threads::shared", 16);
561 shared_magic = mg_find(value, PERL_MAGIC_ext);
562 shared_magic->mg_virtual = &svtable;
563 shared_magic->mg_obj = newSViv(PTR2IV(shared));
564 shared_magic->mg_flags |= MGf_REFCOUNTED;
565 shared_magic->mg_private = 0;
572 MODULE = threads::shared PACKAGE = threads::shared::av
579 shared_sv* shared = Perl_sharedsv_new(aTHX);
580 SV* obj = newSViv(PTR2IV(shared));
581 SHAREDSvEDIT(shared);
582 SHAREDSvGET(shared) = (SV*) newAV();
583 SHAREDSvRELEASE(shared);
589 STORE(self, index, value)
594 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
599 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(value));
601 Perl_croak(aTHX_ "You cannot assign a non shared reference to a shared array");
603 value = newRV_noinc(newSViv(PTR2IV(target)));
605 SHAREDSvLOCK(shared);
606 aentry_ = av_fetch((AV*) SHAREDSvGET(shared), SvIV(index), 0);
607 if(aentry_ && SvIV((*aentry_))) {
609 slot = INT2PTR(shared_sv*, SvIV(aentry));
610 if(SvROK(SHAREDSvGET(slot)))
611 Perl_sharedsv_thrcnt_dec(aTHX_ INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot)))));
613 sv_setsv(SHAREDSvGET(slot), value);
614 SHAREDSvRELEASE(slot);
616 slot = Perl_sharedsv_new(aTHX);
617 SHAREDSvEDIT(shared);
618 SHAREDSvGET(slot) = newSVsv(value);
619 aentry = newSViv(PTR2IV(slot));
620 av_store((AV*) SHAREDSvGET(shared), SvIV(index), aentry);
621 SHAREDSvRELEASE(shared);
623 if(SvROK(SHAREDSvGET(slot)))
624 Perl_sharedsv_thrcnt_inc(aTHX_ INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot)))));
626 SHAREDSvUNLOCK(shared);
633 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
638 SHAREDSvLOCK(shared);
639 aentry_ = av_fetch((AV*) SHAREDSvGET(shared), SvIV(index),0);
642 if(SvTYPE(aentry) == SVt_NULL) {
643 retval = &PL_sv_undef;
645 slot = INT2PTR(shared_sv*, SvIV(aentry));
646 if(SvROK(SHAREDSvGET(slot))) {
647 shared_sv* target = INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot))));
648 retval = Perl_shared_sv_attach_sv(aTHX_ NULL,target);
650 retval = newSVsv(SHAREDSvGET(slot));
654 retval = &PL_sv_undef;
656 SHAREDSvUNLOCK(shared);
665 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
667 SHAREDSvLOCK(shared);
668 for(i = 1; i < items; i++) {
669 shared_sv* slot = Perl_sharedsv_new(aTHX);
672 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(tmp));
674 Perl_croak(aTHX_ "You cannot assign a non shared reference to a shared array");
676 tmp = newRV_noinc(newSViv(PTR2IV(target)));
679 SHAREDSvGET(slot) = newSVsv(tmp);
680 av_push((AV*) SHAREDSvGET(shared), newSViv(PTR2IV(slot)));
681 SHAREDSvRELEASE(slot);
682 if(SvROK(SHAREDSvGET(slot)))
683 Perl_sharedsv_thrcnt_inc(aTHX_ INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot)))));
685 SHAREDSvUNLOCK(shared);
691 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
693 SHAREDSvLOCK(shared);
694 SHAREDSvEDIT(shared);
695 av_unshift((AV*)SHAREDSvGET(shared), items - 1);
696 SHAREDSvRELEASE(shared);
697 for(i = 1; i < items; i++) {
698 shared_sv* slot = Perl_sharedsv_new(aTHX);
701 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(tmp));
703 Perl_croak(aTHX_ "You cannot assign a non shared reference to a shared array");
705 tmp = newRV_noinc(newSViv(PTR2IV(target)));
708 SHAREDSvGET(slot) = newSVsv(tmp);
709 av_store((AV*) SHAREDSvGET(shared), i - 1, newSViv(PTR2IV(slot)));
710 SHAREDSvRELEASE(slot);
711 if(SvROK(SHAREDSvGET(slot)))
712 Perl_sharedsv_thrcnt_inc(aTHX_ INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot)))));
714 SHAREDSvUNLOCK(shared);
720 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
723 SHAREDSvLOCK(shared);
724 SHAREDSvEDIT(shared);
725 retval = av_pop((AV*)SHAREDSvGET(shared));
726 SHAREDSvRELEASE(shared);
727 if(retval && SvIV(retval)) {
728 slot = INT2PTR(shared_sv*, SvIV(retval));
729 if(SvROK(SHAREDSvGET(slot))) {
730 shared_sv* target = INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot))));
731 retval = Perl_shared_sv_attach_sv(aTHX_ NULL,target);
733 retval = newSVsv(SHAREDSvGET(slot));
735 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
737 retval = &PL_sv_undef;
739 SHAREDSvUNLOCK(shared);
749 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
752 SHAREDSvLOCK(shared);
753 SHAREDSvEDIT(shared);
754 retval = av_shift((AV*)SHAREDSvGET(shared));
755 SHAREDSvRELEASE(shared);
756 if(retval && SvIV(retval)) {
757 slot = INT2PTR(shared_sv*, SvIV(retval));
758 if(SvROK(SHAREDSvGET(slot))) {
759 shared_sv* target = INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot))));
760 retval = Perl_shared_sv_attach_sv(aTHX_ NULL,target);
762 retval = newSVsv(SHAREDSvGET(slot));
764 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
766 retval = &PL_sv_undef;
768 SHAREDSvUNLOCK(shared);
777 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
781 SHAREDSvLOCK(shared);
782 svp = AvARRAY((AV*)SHAREDSvGET(shared));
783 i = AvFILLp((AV*)SHAREDSvGET(shared));
786 Perl_sharedsv_thrcnt_dec(aTHX_ INT2PTR(shared_sv*, SvIV(svp[i])));
790 SHAREDSvEDIT(shared);
791 av_clear((AV*)SHAREDSvGET(shared));
792 SHAREDSvRELEASE(shared);
793 SHAREDSvUNLOCK(shared);
800 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
801 SHAREDSvEDIT(shared);
802 av_extend((AV*)SHAREDSvGET(shared), (I32) SvIV(count));
803 SHAREDSvRELEASE(shared);
813 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
815 SHAREDSvLOCK(shared);
816 exists = av_exists((AV*) SHAREDSvGET(shared), (I32) SvIV(index));
822 SHAREDSvUNLOCK(shared);
825 STORESIZE(self,count)
829 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
830 SHAREDSvEDIT(shared);
831 av_fill((AV*) SHAREDSvGET(shared), (I32) SvIV(count));
832 SHAREDSvRELEASE(shared);
838 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
839 SHAREDSvLOCK(shared);
840 RETVAL = newSViv(av_len((AV*) SHAREDSvGET(shared)) + 1);
841 SHAREDSvUNLOCK(shared);
850 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
852 SHAREDSvLOCK(shared);
853 if(av_exists((AV*) SHAREDSvGET(shared), (I32) SvIV(index))) {
855 SHAREDSvEDIT(shared);
856 tmp = av_delete((AV*)SHAREDSvGET(shared), (I32) SvIV(index),0);
857 SHAREDSvRELEASE(shared);
859 slot = INT2PTR(shared_sv*, SvIV(tmp));
860 if(SvROK(SHAREDSvGET(slot))) {
861 shared_sv* target = INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot))));
862 RETVAL = Perl_shared_sv_attach_sv(aTHX_ NULL,target);
864 RETVAL = newSVsv(SHAREDSvGET(slot));
866 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
868 RETVAL = &PL_sv_undef;
871 RETVAL = &PL_sv_undef;
873 SHAREDSvUNLOCK(shared);
878 SPLICE(self, offset, length, ...)
883 croak("Splice is not implmented for shared arrays");
885 MODULE = threads::shared PACKAGE = threads::shared::hv
892 shared_sv* shared = Perl_sharedsv_new(aTHX);
893 SV* obj = newSViv(PTR2IV(shared));
894 SHAREDSvEDIT(shared);
895 SHAREDSvGET(shared) = (SV*) newHV();
896 SHAREDSvRELEASE(shared);
902 STORE(self, key, value)
907 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
912 char* ckey = SvPV(key, len);
913 SHAREDSvLOCK(shared);
915 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(value));
917 Perl_croak(aTHX_ "You cannot assign a non shared reference to a shared hash");
919 SHAREDSvEDIT(shared);
920 value = newRV_noinc(newSViv(PTR2IV(target)));
921 SHAREDSvRELEASE(shared);
923 hentry_ = hv_fetch((HV*) SHAREDSvGET(shared), ckey, len, 0);
924 if(hentry_ && SvIV((*hentry_))) {
926 slot = INT2PTR(shared_sv*, SvIV(hentry));
927 if(SvROK(SHAREDSvGET(slot)))
928 Perl_sharedsv_thrcnt_dec(aTHX_ INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot)))));
930 sv_setsv(SHAREDSvGET(slot), value);
931 SHAREDSvRELEASE(slot);
933 slot = Perl_sharedsv_new(aTHX);
934 SHAREDSvEDIT(shared);
935 SHAREDSvGET(slot) = newSVsv(value);
936 hentry = newSViv(PTR2IV(slot));
937 hv_store((HV*) SHAREDSvGET(shared), ckey,len , hentry, 0);
938 SHAREDSvRELEASE(shared);
940 if(SvROK(SHAREDSvGET(slot)))
941 Perl_sharedsv_thrcnt_inc(aTHX_ INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot)))));
942 SHAREDSvUNLOCK(shared);
950 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
956 char* ckey = SvPV(key, len);
957 SHAREDSvLOCK(shared);
958 hentry_ = hv_fetch((HV*) SHAREDSvGET(shared), ckey, len,0);
961 if(SvTYPE(hentry) == SVt_NULL) {
962 retval = &PL_sv_undef;
964 slot = INT2PTR(shared_sv*, SvIV(hentry));
965 if(SvROK(SHAREDSvGET(slot))) {
966 shared_sv* target = INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot))));
967 retval = Perl_shared_sv_attach_sv(aTHX_ NULL, target);
969 retval = newSVsv(SHAREDSvGET(slot));
973 retval = &PL_sv_undef;
975 SHAREDSvUNLOCK(shared);
984 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
987 SHAREDSvLOCK(shared);
988 Perl_hv_iterinit(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
989 entry = Perl_hv_iternext(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
991 slot = INT2PTR(shared_sv*, SvIV(Perl_hv_iterval(PL_sharedsv_space, (HV*) SHAREDSvGET(shared), entry)));
992 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
993 entry = Perl_hv_iternext(PL_sharedsv_space,(HV*) SHAREDSvGET(shared));
995 SHAREDSvEDIT(shared);
996 hv_clear((HV*) SHAREDSvGET(shared));
997 SHAREDSvRELEASE(shared);
998 SHAREDSvUNLOCK(shared);
1004 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
1008 SHAREDSvLOCK(shared);
1009 Perl_hv_iterinit(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
1010 entry = Perl_hv_iternext(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
1012 key = Perl_hv_iterkey(PL_sharedsv_space, entry,&len);
1013 RETVAL = newSVpv(key, len);
1015 RETVAL = &PL_sv_undef;
1017 SHAREDSvUNLOCK(shared);
1023 NEXTKEY(self, oldkey)
1027 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
1031 SHAREDSvLOCK(shared);
1032 entry = Perl_hv_iternext(PL_sharedsv_space, (HV*) SHAREDSvGET(shared));
1034 key = Perl_hv_iterkey(PL_sharedsv_space, entry,&len);
1035 RETVAL = newSVpv(key, len);
1037 RETVAL = &PL_sv_undef;
1039 SHAREDSvUNLOCK(shared);
1049 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
1051 char* ckey = SvPV(key, len);
1052 SHAREDSvLOCK(shared);
1053 if(hv_exists((HV*)SHAREDSvGET(shared), ckey, len)) {
1054 RETVAL = &PL_sv_yes;
1058 SHAREDSvUNLOCK(shared);
1067 shared_sv* shared = INT2PTR(shared_sv*, SvIV(SvRV(self)));
1070 char* ckey = SvPV(key, len);
1072 SHAREDSvLOCK(shared);
1073 SHAREDSvEDIT(shared);
1074 tmp = hv_delete((HV*) SHAREDSvGET(shared), ckey, len,0);
1075 SHAREDSvRELEASE(shared);
1077 slot = INT2PTR(shared_sv*, SvIV(tmp));
1078 if(SvROK(SHAREDSvGET(slot))) {
1079 shared_sv* target = INT2PTR(shared_sv*, SvIV(SvRV(SHAREDSvGET(slot))));
1080 RETVAL = Perl_shared_sv_attach_sv(aTHX_ NULL, target);
1082 RETVAL = newSVsv(SHAREDSvGET(slot));
1084 Perl_sharedsv_thrcnt_dec(aTHX_ slot);
1086 RETVAL = &PL_sv_undef;
1088 SHAREDSvUNLOCK(shared);
1094 Perl_sharedsv_init(aTHX);