This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Make AIX and Tru64 compilers happy.
[perl5.git] / sharedsv.c
CommitLineData
cd1ee231
JH
1/* sharedsv.c
2 *
3 * Copyright (c) 2001, Larry Wall
4 *
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.
7 *
8 */
9
10/*
11* Contributed by Arthur Bergman arthur@contiller.se
12*
13* "Hand any two wizards a piece of rope and they would instinctively pull in
14* opposite directions."
15* --Sourcery
16*
17*/
18
19#include "EXTERN.h"
20#define PERL_IN_SHAREDSV_C
21#include "perl.h"
22
0a66a22f
RGS
23#ifdef USE_ITHREADS
24
4f896ddc 25
cd1ee231 26
cd1ee231
JH
27/*
28 Shared SV
29
30 Shared SV is a structure for keeping the backend storage
31 of shared svs.
32
33 */
34
35/*
36=for apidoc sharedsv_init
37
38Saves a space for keeping SVs wider than an interpreter,
39currently only stores a pointer to the first interpreter.
40
41=cut
42*/
43
44void
45Perl_sharedsv_init(pTHX)
46{
4f896ddc
AB
47 PL_sharedsv_space = PERL_GET_CONTEXT;
48 MUTEX_INIT(&PL_sharedsv_space_mutex);
cd1ee231
JH
49}
50
51/*
52=for apidoc sharedsv_new
53
54Allocates a new shared sv struct, you must yourself create the SV/AV/HV.
55=cut
56*/
57
58shared_sv *
59Perl_sharedsv_new(pTHX)
60{
61 shared_sv* ssv;
62 New(2555,ssv,1,shared_sv);
63 MUTEX_INIT(&ssv->mutex);
64 COND_INIT(&ssv->cond);
39696b0c
AB
65 COND_INIT(&ssv->user_cond);
66 ssv->owner = 0;
cd1ee231
JH
67 ssv->locks = 0;
68 return ssv;
69}
70
71
72/*
73=for apidoc sharedsv_find
74
75Tries to find if a given SV has a shared backend, either by
76looking at magic, or by checking if it is tied again threads::shared.
77
78=cut
79*/
80
81shared_sv *
82Perl_sharedsv_find(pTHX_ SV* sv)
83{
84 /* does all it can to find a shared_sv struct, returns NULL otherwise */
85 shared_sv* ssv = NULL;
86 return ssv;
87}
88
89/*
90=for apidoc sharedsv_lock
91
92Recursive locks on a sharedsv.
93Locks are dynamicly scoped at the level of the first lock.
94=cut
95*/
96void
97Perl_sharedsv_lock(pTHX_ shared_sv* ssv)
98{
99 if(!ssv)
100 return;
39696b0c 101 MUTEX_LOCK(&ssv->mutex);
cd1ee231
JH
102 if(ssv->owner && ssv->owner == my_perl) {
103 ssv->locks++;
39696b0c 104 MUTEX_UNLOCK(&ssv->mutex);
cd1ee231
JH
105 return;
106 }
39696b0c
AB
107 while(ssv->owner)
108 COND_WAIT(&ssv->cond,&ssv->mutex);
cd1ee231
JH
109 ssv->locks++;
110 ssv->owner = my_perl;
111 if(ssv->locks == 1)
112 SAVEDESTRUCTOR_X(Perl_sharedsv_unlock_scope,ssv);
39696b0c 113 MUTEX_UNLOCK(&ssv->mutex);
cd1ee231
JH
114}
115
116/*
117=for apidoc sharedsv_unlock
118
119Recursively unlocks a shared sv.
120
121=cut
122*/
123
124void
125Perl_sharedsv_unlock(pTHX_ shared_sv* ssv)
126{
39696b0c
AB
127 MUTEX_LOCK(&ssv->mutex);
128 if(ssv->owner != my_perl) {
129 Perl_croak(aTHX_ "panic: Perl_sharedsv_unlock unlocking mutex that we don't own");
130 MUTEX_UNLOCK(&ssv->mutex);
cd1ee231 131 return;
39696b0c 132 }
cd1ee231
JH
133
134 if(--ssv->locks == 0) {
135 ssv->owner = NULL;
39696b0c 136 COND_SIGNAL(&ssv->cond);
cd1ee231 137 }
39696b0c 138 MUTEX_UNLOCK(&ssv->mutex);
cd1ee231
JH
139 }
140
141void
142Perl_sharedsv_unlock_scope(pTHX_ shared_sv* ssv)
143{
39696b0c
AB
144 MUTEX_LOCK(&ssv->mutex);
145 if(ssv->owner != my_perl) {
146 MUTEX_UNLOCK(&ssv->mutex);
cd1ee231 147 return;
39696b0c 148 }
cd1ee231
JH
149 ssv->locks = 0;
150 ssv->owner = NULL;
39696b0c 151 COND_SIGNAL(&ssv->cond);
cd1ee231
JH
152 MUTEX_UNLOCK(&ssv->mutex);
153}
154
155/*
156=for apidoc sharedsv_thrcnt_inc
157
158Increments the threadcount of a sharedsv.
159=cut
160*/
161void
162Perl_sharedsv_thrcnt_inc(pTHX_ shared_sv* ssv)
163{
667883b0 164 SHAREDSvEDIT(ssv);
cd1ee231 165 SvREFCNT_inc(ssv->sv);
667883b0 166 SHAREDSvRELEASE(ssv);
cd1ee231
JH
167}
168
169/*
170=for apidoc sharedsv_thrcnt_dec
171
172Decrements the threadcount of a shared sv. When a threads frontend is freed
173this function should be called.
174
175=cut
176*/
177
178void
179Perl_sharedsv_thrcnt_dec(pTHX_ shared_sv* ssv)
180{
181 SV* sv;
cd1ee231
JH
182 SHAREDSvEDIT(ssv);
183 sv = SHAREDSvGET(ssv);
184 if (SvREFCNT(sv) == 1) {
185 switch (SvTYPE(sv)) {
186 case SVt_RV:
187 if (SvROK(sv))
cbfa9890 188 Perl_sharedsv_thrcnt_dec(aTHX_ INT2PTR(shared_sv *, SvIV(SvRV(sv))));
cd1ee231
JH
189 break;
190 case SVt_PVAV: {
191 SV **src_ary = AvARRAY((AV *)sv);
192 SSize_t items = AvFILLp((AV *)sv) + 1;
193
194 while (items-- > 0) {
195 if(SvTYPE(*src_ary))
cbfa9890 196 Perl_sharedsv_thrcnt_dec(aTHX_ INT2PTR(shared_sv *, SvIV(*src_ary++)));
cd1ee231
JH
197 }
198 break;
199 }
200 case SVt_PVHV: {
201 HE *entry;
202 (void)hv_iterinit((HV *)sv);
203 while ((entry = hv_iternext((HV *)sv)))
204 Perl_sharedsv_thrcnt_dec(
cbfa9890 205 aTHX_ INT2PTR(shared_sv *, SvIV(hv_iterval((HV *)sv, entry)))
cd1ee231
JH
206 );
207 break;
208 }
209 }
210 }
211 SvREFCNT_dec(sv);
212 SHAREDSvRELEASE(ssv);
cd1ee231
JH
213}
214
0a66a22f 215#endif /* USE_ITHREADS */
39696b0c 216