#14048 exposed few false positives, to be fixed soonish.
[p5sagit/p5-mst-13.2.git] / ext / threads / shared / shared.pm
CommitLineData
b050c948 1package threads::shared;
2
3use strict;
4use warnings;
5use Config;
6use Scalar::Util qw(weaken);
7use attributes qw(reftype);
8
9BEGIN {
9ece3ee6 10 if($Config{'useithreads'} && $threads::threads) {
b050c948 11 *share = \&share_enabled;
6f942b98 12 *cond_wait = \&cond_wait_enabled;
13 *cond_signal = \&cond_signal_enabled;
14 *cond_broadcast = \&cond_broadcast_enabled;
15 *unlock = \&unlock_enabled;
a6b94e59 16 } else {
17 *share = \&share_disabled;
18 *cond_wait = \&cond_wait_disabled;
19 *cond_signal = \&cond_signal_disabled;
dab065ea 20 *cond_broadcast = \&cond_broadcast_disabled;
a6b94e59 21 *unlock = \&unlock_disabled;
b050c948 22 }
23}
24
25require Exporter;
26require DynaLoader;
27our @ISA = qw(Exporter DynaLoader);
28
a6b94e59 29our @EXPORT = qw(share cond_wait cond_broadcast cond_signal unlock);
515f0976 30our $VERSION = '0.90';
b050c948 31
32our %shared;
33
b050c948 34sub cond_wait_disabled { return @_ };
35sub cond_signal_disabled { return @_};
36sub cond_broadcast_disabled { return @_};
37sub unlock_disabled { 1 };
38sub lock_disabled { 1 }
39sub share_disabled { return @_}
40
41sub share_enabled (\[$@%]) { # \]
42 my $value = $_[0];
43 my $ref = reftype($value);
44 if($ref eq 'SCALAR') {
aaf3876d 45 my $obj = \threads::shared::sv->new($$value);
46 bless $obj, 'threads::shared::sv';
47 $shared{$$obj} = $value;
48 weaken($shared{$$obj});
49 } elsif($ref eq "ARRAY") {
50 tie @$value, 'threads::shared::av', $value;
8669ce85 51 } elsif($ref eq "HASH") {
52 tie %$value, "threads::shared::hv", $value;
b050c948 53 } else {
54 die "You cannot share ref of type $_[0]\n";
55 }
56}
57
58sub CLONE {
59 return unless($_[0] eq "threads::shared");
60 foreach my $ptr (keys %shared) {
61 if($ptr) {
cd8c9bf8 62 thrcnt_inc($shared{$ptr},$threads::origthread);
b050c948 63 }
64 }
65}
66
aaf3876d 67sub DESTROY {
68 my $self = shift;
866fba46 69 _thrcnt_dec($$self);
aaf3876d 70 delete($shared{$$self});
71}
72
b050c948 73package threads::shared::sv;
74use base 'threads::shared';
75
aaf3876d 76sub DESTROY {}
77
b050c948 78package threads::shared::av;
79use base 'threads::shared';
aaf3876d 80use Scalar::Util qw(weaken);
81sub TIEARRAY {
82 my $class = shift;
83 my $value = shift;
84 my $self = bless \threads::shared::av->new($value),'threads::shared::av';
85 $shared{$self->ptr} = $value;
86 weaken($shared{$self->ptr});
87 return $self;
88}
b050c948 89
90package threads::shared::hv;
91use base 'threads::shared';
8669ce85 92use Scalar::Util qw(weaken);
93sub TIEHASH {
94 my $class = shift;
95 my $value = shift;
96 my $self = bless \threads::shared::hv->new($value),'threads::shared::hv';
97 $shared{$self->ptr} = $value;
98 weaken($shared{$self->ptr});
99 return $self;
100}
b050c948 101
8669ce85 102package threads::shared;
dab065ea 103
104$threads::shared::threads_shared = 1;
105
b050c948 106bootstrap threads::shared $VERSION;
107
108__END__
109
110=head1 NAME
111
112threads::shared - Perl extension for sharing data structures between threads
113
114=head1 SYNOPSIS
115
116 use threads::shared;
117
118 my($foo, @foo, %foo);
aaf3876d 119 share($foo);
120 share(@foo);
121 share(%hash);
b050c948 122 my $bar = share([]);
123 $hash{bar} = share({});
124
515f0976 125 lock(%hash);
126 unlock(%hash);
b050c948 127 cond_wait($scalar);
515f0976 128 cond_broadcast(@array);
129 cond_signal(%hash);
b050c948 130
131=head1 DESCRIPTION
132
ad91d581 133This modules allows you to share() variables. These variables will
134then be shared across different threads (and pseudoforks on
135win32). They are used together with the threads module.
b050c948 136
515f0976 137=head1 EXPORT
b050c948 138
515f0976 139C<share>, C<lock>, C<unlock>, C<cond_wait>, C<cond_signal>, C<cond_broadcast>
140
141=head1 FUNCTIONS
142
143=over 4
144
145=item share VARIABLE
146
d1be9408 147C<share> takes a value and marks it as shared, you can share a scalar, array, hash
515f0976 148scalar ref, array ref and hash ref, C<share> will return the shared value.
149
150C<share> will traverse up references exactly I<one> level.
151C<share(\$a)> is equivalent to C<share($a)>, while C<share(\\$a)> is not.
152
153=item lock VARIABLE
154
155C<lock> places a lock on a variable until the lock goes out of scope. If
156the variable is locked by another thread, the C<lock> call will block until
157it's available. C<lock> is recursive, so multiple calls to C<lock> are
158safe--the variable will remain locked until the outermost lock on the
159variable goes out of scope or C<unlock> is called enough times to match
160the number of calls to <lock>.
161
162If a container object, such as a hash or array, is locked, all the elements
163of that container are not locked. For example, if a thread does a C<lock
164@a>, any other thread doing a C<lock($a[12])> won't block.
165
166C<lock> will traverse up references exactly I<one> level.
167C<lock(\$a)> is equivalent to C<lock($a)>, while C<lock(\\$a)> is not.
168
169
170=item unlock VARIABLE
171
172C<unlock> takes a locked shared value and decrements the lock count.
173If the lock count is zero the variable is unlocked. It is not necessary
174to call C<unlock> but it can be usefull to reduce lock contention.
175
176C<unlock> will traverse up references exactly I<one> level.
177C<unlock(\$a)> is equivalent to C<unlock($a)>, while C<unlock(\\$a)> is not.
178
179=item cond_wait VARIABLE
180
181The C<cond_wait> function takes a B<locked> variable as a parameter,
182unlocks the variable, and blocks until another thread does a C<cond_signal>
183or C<cond_broadcast> for that same locked variable. The variable that
184C<cond_wait> blocked on is relocked after the C<cond_wait> is satisfied.
185If there are multiple threads C<cond_wait>ing on the same variable, all but
186one will reblock waiting to reaquire the lock on the variable. (So if
187you're only using C<cond_wait> for synchronization, give up the lock as
188soon as possible)
189
190It is important to note that the variable can be notified even if no
191thread C<cond_signal> or C<cond_broadcast> on the variable. It is therefore
192important to check the value of the variable and go back to waiting if the
193requirment is not fullfilled.
194
195=item cond_signal VARIABLE
196
197The C<cond_signal> function takes a B<locked> variable as a parameter and
198unblocks one thread that's C<cond_wait>ing on that variable. If more than
199one thread is blocked in a C<cond_wait> on that variable, only one (and
200which one is indeterminate) will be unblocked.
201
202If there are no threads blocked in a C<cond_wait> on the variable, the
203signal is discarded.
204
205=item cond_broadcast VARIABLE
206
207The C<cond_broadcast> function works similarly to C<cond_signal>.
208C<cond_broadcast>, though, will unblock B<all> the threads that are blocked
209in a C<cond_wait> on the locked variable, rather than only one.
b050c948 210
dab065ea 211
212=head1 NOTES
213
214threads::shared is designed is disable itself silently if threads are
215not available. If you want access to threads, you must C<use threads>
216before you C<use threads::shared>. threads will emit a warning if you
217use it before threads::shared.
218
b050c948 219=head1 BUGS
220
515f0976 221C<bless> is not supported on shared references, in the current version
222C<bless> will only bless the thread local reference and the blessing
223will not propagate to the other threads, this is expected to be implmented
224in the future.
225
b050c948 226Does not support splice on arrays!
b050c948 227
228=head1 AUTHOR
229
aaf3876d 230Arthur Bergman E<lt>arthur at contiller.seE<gt>
b050c948 231
aaf3876d 232threads::shared is released under the same license as Perl
b050c948 233
515f0976 234Documentation borrowed from Thread.pm
235
b050c948 236=head1 SEE ALSO
237
238L<perl> L<threads>
239
240=cut
515f0976 241
242
243
244
245