xref: /openbsd-src/gnu/usr.bin/perl/dist/threads-shared/lib/threads/shared.pm (revision 3d61058aa5c692477b6d18acfbbdb653a9930ff9)
1898184e3Ssthenpackage threads::shared;
2898184e3Ssthen
3898184e3Ssthenuse 5.008;
4898184e3Ssthen
5898184e3Ssthenuse strict;
6898184e3Ssthenuse warnings;
7b46d8ef2Safresh1use Config;
8898184e3Ssthen
9898184e3Ssthenuse Scalar::Util qw(reftype refaddr blessed);
10898184e3Ssthen
11*3d61058aSafresh1our $VERSION = '1.69'; # Please update the pod, too.
12898184e3Ssthenmy $XS_VERSION = $VERSION;
13898184e3Ssthen$VERSION = eval $VERSION;
14898184e3Ssthen
15898184e3Ssthen# Declare that we have been loaded
16898184e3Ssthen$threads::shared::threads_shared = 1;
17898184e3Ssthen
1891f110e0Safresh1# Method of complaint about things we can't clone
1991f110e0Safresh1$threads::shared::clone_warn = undef;
2091f110e0Safresh1
21898184e3Ssthen# Load the XS code, if applicable
22b46d8ef2Safresh1if ($Config::Config{'useithreads'} && $threads::threads) {
23898184e3Ssthen    require XSLoader;
24898184e3Ssthen    XSLoader::load('threads::shared', $XS_VERSION);
25898184e3Ssthen
26898184e3Ssthen    *is_shared = \&_id;
27898184e3Ssthen
28898184e3Ssthen} else {
29898184e3Ssthen    # String eval is generally evil, but we don't want these subs to
30898184e3Ssthen    # exist at all if 'threads' is not loaded successfully.
31898184e3Ssthen    # Vivifying them conditionally this way saves on average about 4K
32898184e3Ssthen    # of memory per thread.
33898184e3Ssthen    eval <<'_MARKER_';
34898184e3Ssthen        sub share          (\[$@%])         { return $_[0] }
35898184e3Ssthen        sub is_shared      (\[$@%])         { undef }
36898184e3Ssthen        sub cond_wait      (\[$@%];\[$@%])  { undef }
37898184e3Ssthen        sub cond_timedwait (\[$@%]$;\[$@%]) { undef }
38898184e3Ssthen        sub cond_signal    (\[$@%])         { undef }
39898184e3Ssthen        sub cond_broadcast (\[$@%])         { undef }
40898184e3Ssthen_MARKER_
41898184e3Ssthen}
42898184e3Ssthen
43898184e3Ssthen
44898184e3Ssthen### Export ###
45898184e3Ssthen
46898184e3Ssthensub import
47898184e3Ssthen{
48898184e3Ssthen    # Exported subroutines
49898184e3Ssthen    my @EXPORT = qw(share is_shared cond_wait cond_timedwait
50898184e3Ssthen                    cond_signal cond_broadcast shared_clone);
51898184e3Ssthen    if ($threads::threads) {
52898184e3Ssthen        push(@EXPORT, 'bless');
53898184e3Ssthen    }
54898184e3Ssthen
55898184e3Ssthen    # Export subroutine names
56898184e3Ssthen    my $caller = caller();
57898184e3Ssthen    foreach my $sym (@EXPORT) {
58898184e3Ssthen        no strict 'refs';
59898184e3Ssthen        *{$caller.'::'.$sym} = \&{$sym};
60898184e3Ssthen    }
61898184e3Ssthen}
62898184e3Ssthen
63898184e3Ssthen
64898184e3Ssthen# Predeclarations for internal functions
65898184e3Ssthenmy ($make_shared);
66898184e3Ssthen
67898184e3Ssthen
68898184e3Ssthen### Methods, etc. ###
69898184e3Ssthen
70898184e3Ssthensub threads::shared::tie::SPLICE
71898184e3Ssthen{
72898184e3Ssthen    require Carp;
73898184e3Ssthen    Carp::croak('Splice not implemented for shared arrays');
74898184e3Ssthen}
75898184e3Ssthen
76898184e3Ssthen
77898184e3Ssthen# Create a thread-shared clone of a complex data structure or object
78898184e3Ssthensub shared_clone
79898184e3Ssthen{
80898184e3Ssthen    if (@_ != 1) {
81898184e3Ssthen        require Carp;
82898184e3Ssthen        Carp::croak('Usage: shared_clone(REF)');
83898184e3Ssthen    }
84898184e3Ssthen
85898184e3Ssthen    return $make_shared->(shift, {});
86898184e3Ssthen}
87898184e3Ssthen
88898184e3Ssthen
89898184e3Ssthen### Internal Functions ###
90898184e3Ssthen
91898184e3Ssthen# Used by shared_clone() to recursively clone
92898184e3Ssthen#   a complex data structure or object
93898184e3Ssthen$make_shared = sub {
94898184e3Ssthen    my ($item, $cloned) = @_;
95898184e3Ssthen
96898184e3Ssthen    # Just return the item if:
97898184e3Ssthen    # 1. Not a ref;
98898184e3Ssthen    # 2. Already shared; or
99898184e3Ssthen    # 3. Not running 'threads'.
100898184e3Ssthen    return $item if (! ref($item) || is_shared($item) || ! $threads::threads);
101898184e3Ssthen
102898184e3Ssthen    # Check for previously cloned references
103898184e3Ssthen    #   (this takes care of circular refs as well)
104898184e3Ssthen    my $addr = refaddr($item);
105898184e3Ssthen    if (exists($cloned->{$addr})) {
106898184e3Ssthen        # Return the already existing clone
107898184e3Ssthen        return $cloned->{$addr};
108898184e3Ssthen    }
109898184e3Ssthen
110898184e3Ssthen    # Make copies of array, hash and scalar refs and refs of refs
111898184e3Ssthen    my $copy;
112898184e3Ssthen    my $ref_type = reftype($item);
113898184e3Ssthen
114898184e3Ssthen    # Copy an array ref
115898184e3Ssthen    if ($ref_type eq 'ARRAY') {
116898184e3Ssthen        # Make empty shared array ref
117898184e3Ssthen        $copy = &share([]);
118898184e3Ssthen        # Add to clone checking hash
119898184e3Ssthen        $cloned->{$addr} = $copy;
120898184e3Ssthen        # Recursively copy and add contents
121898184e3Ssthen        push(@$copy, map { $make_shared->($_, $cloned) } @$item);
122898184e3Ssthen    }
123898184e3Ssthen
124898184e3Ssthen    # Copy a hash ref
125898184e3Ssthen    elsif ($ref_type eq 'HASH') {
126898184e3Ssthen        # Make empty shared hash ref
127898184e3Ssthen        $copy = &share({});
128898184e3Ssthen        # Add to clone checking hash
129898184e3Ssthen        $cloned->{$addr} = $copy;
130898184e3Ssthen        # Recursively copy and add contents
131898184e3Ssthen        foreach my $key (keys(%{$item})) {
132898184e3Ssthen            $copy->{$key} = $make_shared->($item->{$key}, $cloned);
133898184e3Ssthen        }
134898184e3Ssthen    }
135898184e3Ssthen
136898184e3Ssthen    # Copy a scalar ref
137898184e3Ssthen    elsif ($ref_type eq 'SCALAR') {
138898184e3Ssthen        $copy = \do{ my $scalar = $$item; };
139898184e3Ssthen        share($copy);
140898184e3Ssthen        # Add to clone checking hash
141898184e3Ssthen        $cloned->{$addr} = $copy;
142898184e3Ssthen    }
143898184e3Ssthen
144898184e3Ssthen    # Copy of a ref of a ref
145898184e3Ssthen    elsif ($ref_type eq 'REF') {
146898184e3Ssthen        # Special handling for $x = \$x
147898184e3Ssthen        if ($addr == refaddr($$item)) {
148898184e3Ssthen            $copy = \$copy;
149898184e3Ssthen            share($copy);
150898184e3Ssthen            $cloned->{$addr} = $copy;
151898184e3Ssthen        } else {
152898184e3Ssthen            my $tmp;
153898184e3Ssthen            $copy = \$tmp;
154898184e3Ssthen            share($copy);
155898184e3Ssthen            # Add to clone checking hash
156898184e3Ssthen            $cloned->{$addr} = $copy;
157898184e3Ssthen            # Recursively copy and add contents
158898184e3Ssthen            $tmp = $make_shared->($$item, $cloned);
159898184e3Ssthen        }
160898184e3Ssthen
161898184e3Ssthen    } else {
162898184e3Ssthen        require Carp;
16391f110e0Safresh1        if (! defined($threads::shared::clone_warn)) {
164898184e3Ssthen            Carp::croak("Unsupported ref type: ", $ref_type);
16591f110e0Safresh1        } elsif ($threads::shared::clone_warn) {
16691f110e0Safresh1            Carp::carp("Unsupported ref type: ", $ref_type);
16791f110e0Safresh1        }
16891f110e0Safresh1        return undef;
169898184e3Ssthen    }
170898184e3Ssthen
171898184e3Ssthen    # If input item is an object, then bless the copy into the same class
172898184e3Ssthen    if (my $class = blessed($item)) {
173898184e3Ssthen        bless($copy, $class);
174898184e3Ssthen    }
175898184e3Ssthen
176898184e3Ssthen    # Clone READONLY flag
177898184e3Ssthen    if ($ref_type eq 'SCALAR') {
178898184e3Ssthen        if (Internals::SvREADONLY($$item)) {
179898184e3Ssthen            Internals::SvREADONLY($$copy, 1) if ($] >= 5.008003);
180898184e3Ssthen        }
181898184e3Ssthen    }
182898184e3Ssthen    if (Internals::SvREADONLY($item)) {
183898184e3Ssthen        Internals::SvREADONLY($copy, 1) if ($] >= 5.008003);
184898184e3Ssthen    }
185898184e3Ssthen
186898184e3Ssthen    return $copy;
187898184e3Ssthen};
188898184e3Ssthen
189898184e3Ssthen1;
190898184e3Ssthen
191898184e3Ssthen__END__
192898184e3Ssthen
193898184e3Ssthen=head1 NAME
194898184e3Ssthen
195898184e3Ssthenthreads::shared - Perl extension for sharing data structures between threads
196898184e3Ssthen
197898184e3Ssthen=head1 VERSION
198898184e3Ssthen
199e0680481Safresh1This document describes threads::shared version 1.68
200898184e3Ssthen
201898184e3Ssthen=head1 SYNOPSIS
202898184e3Ssthen
203898184e3Ssthen  use threads;
204898184e3Ssthen  use threads::shared;
205898184e3Ssthen
206898184e3Ssthen  my $var :shared;
207898184e3Ssthen  my %hsh :shared;
208898184e3Ssthen  my @ary :shared;
209898184e3Ssthen
210898184e3Ssthen  my ($scalar, @array, %hash);
211898184e3Ssthen  share($scalar);
212898184e3Ssthen  share(@array);
213898184e3Ssthen  share(%hash);
214898184e3Ssthen
215898184e3Ssthen  $var = $scalar_value;
216898184e3Ssthen  $var = $shared_ref_value;
217898184e3Ssthen  $var = shared_clone($non_shared_ref_value);
218898184e3Ssthen  $var = shared_clone({'foo' => [qw/foo bar baz/]});
219898184e3Ssthen
220898184e3Ssthen  $hsh{'foo'} = $scalar_value;
221898184e3Ssthen  $hsh{'bar'} = $shared_ref_value;
222898184e3Ssthen  $hsh{'baz'} = shared_clone($non_shared_ref_value);
223898184e3Ssthen  $hsh{'quz'} = shared_clone([1..3]);
224898184e3Ssthen
225898184e3Ssthen  $ary[0] = $scalar_value;
226898184e3Ssthen  $ary[1] = $shared_ref_value;
227898184e3Ssthen  $ary[2] = shared_clone($non_shared_ref_value);
228898184e3Ssthen  $ary[3] = shared_clone([ {}, [] ]);
229898184e3Ssthen
230898184e3Ssthen  { lock(%hash); ...  }
231898184e3Ssthen
232898184e3Ssthen  cond_wait($scalar);
233898184e3Ssthen  cond_timedwait($scalar, time() + 30);
234898184e3Ssthen  cond_broadcast(@array);
235898184e3Ssthen  cond_signal(%hash);
236898184e3Ssthen
237898184e3Ssthen  my $lockvar :shared;
238898184e3Ssthen  # condition var != lock var
239898184e3Ssthen  cond_wait($var, $lockvar);
240898184e3Ssthen  cond_timedwait($var, time()+30, $lockvar);
241898184e3Ssthen
242898184e3Ssthen=head1 DESCRIPTION
243898184e3Ssthen
244898184e3SsthenBy default, variables are private to each thread, and each newly created
245898184e3Ssthenthread gets a private copy of each existing variable.  This module allows you
246898184e3Ssthento share variables across different threads (and pseudo-forks on Win32).  It
247898184e3Ssthenis used together with the L<threads> module.
248898184e3Ssthen
249898184e3SsthenThis module supports the sharing of the following data types only:  scalars
250898184e3Ssthenand scalar refs, arrays and array refs, and hashes and hash refs.
251898184e3Ssthen
252898184e3Ssthen=head1 EXPORT
253898184e3Ssthen
254898184e3SsthenThe following functions are exported by this module: C<share>,
255898184e3SsthenC<shared_clone>, C<is_shared>, C<cond_wait>, C<cond_timedwait>, C<cond_signal>
256898184e3Ssthenand C<cond_broadcast>
257898184e3Ssthen
258898184e3SsthenNote that if this module is imported when L<threads> has not yet been loaded,
259898184e3Ssthenthen these functions all become no-ops.  This makes it possible to write
260898184e3Ssthenmodules that will work in both threaded and non-threaded environments.
261898184e3Ssthen
262898184e3Ssthen=head1 FUNCTIONS
263898184e3Ssthen
264898184e3Ssthen=over 4
265898184e3Ssthen
266898184e3Ssthen=item share VARIABLE
267898184e3Ssthen
268898184e3SsthenC<share> takes a variable and marks it as shared:
269898184e3Ssthen
270898184e3Ssthen  my ($scalar, @array, %hash);
271898184e3Ssthen  share($scalar);
272898184e3Ssthen  share(@array);
273898184e3Ssthen  share(%hash);
274898184e3Ssthen
275898184e3SsthenC<share> will return the shared rvalue, but always as a reference.
276898184e3Ssthen
277898184e3SsthenVariables can also be marked as shared at compile time by using the
278898184e3SsthenC<:shared> attribute:
279898184e3Ssthen
280898184e3Ssthen  my ($var, %hash, @array) :shared;
281898184e3Ssthen
282898184e3SsthenShared variables can only store scalars, refs of shared variables, or
283898184e3Ssthenrefs of shared data (discussed in next section):
284898184e3Ssthen
285898184e3Ssthen  my ($var, %hash, @array) :shared;
286898184e3Ssthen  my $bork;
287898184e3Ssthen
288898184e3Ssthen  # Storing scalars
289898184e3Ssthen  $var = 1;
290898184e3Ssthen  $hash{'foo'} = 'bar';
291898184e3Ssthen  $array[0] = 1.5;
292898184e3Ssthen
293898184e3Ssthen  # Storing shared refs
294898184e3Ssthen  $var = \%hash;
295898184e3Ssthen  $hash{'ary'} = \@array;
296898184e3Ssthen  $array[1] = \$var;
297898184e3Ssthen
298898184e3Ssthen  # The following are errors:
299898184e3Ssthen  #   $var = \$bork;                    # ref of non-shared variable
300898184e3Ssthen  #   $hash{'bork'} = [];               # non-shared array ref
301898184e3Ssthen  #   push(@array, { 'x' => 1 });       # non-shared hash ref
302898184e3Ssthen
303898184e3Ssthen=item shared_clone REF
304898184e3Ssthen
305898184e3SsthenC<shared_clone> takes a reference, and returns a shared version of its
306898184e3Ssthenargument, performing a deep copy on any non-shared elements.  Any shared
307898184e3Ssthenelements in the argument are used as is (i.e., they are not cloned).
308898184e3Ssthen
309898184e3Ssthen  my $cpy = shared_clone({'foo' => [qw/foo bar baz/]});
310898184e3Ssthen
311898184e3SsthenObject status (i.e., the class an object is blessed into) is also cloned.
312898184e3Ssthen
313898184e3Ssthen  my $obj = {'foo' => [qw/foo bar baz/]};
314898184e3Ssthen  bless($obj, 'Foo');
315898184e3Ssthen  my $cpy = shared_clone($obj);
316898184e3Ssthen  print(ref($cpy), "\n");         # Outputs 'Foo'
317898184e3Ssthen
318898184e3SsthenFor cloning empty array or hash refs, the following may also be used:
319898184e3Ssthen
320898184e3Ssthen  $var = &share([]);   # Same as $var = shared_clone([]);
321898184e3Ssthen  $var = &share({});   # Same as $var = shared_clone({});
322898184e3Ssthen
32391f110e0Safresh1Not all Perl data types can be cloned (e.g., globs, code refs).  By default,
32491f110e0Safresh1C<shared_clone> will L<croak|Carp> if it encounters such items.  To change
32591f110e0Safresh1this behaviour to a warning, then set the following:
32691f110e0Safresh1
32791f110e0Safresh1  $threads::shared::clone_warn = 1;
32891f110e0Safresh1
32991f110e0Safresh1In this case, C<undef> will be substituted for the item to be cloned.  If
33091f110e0Safresh1set to zero:
33191f110e0Safresh1
33291f110e0Safresh1  $threads::shared::clone_warn = 0;
33391f110e0Safresh1
33491f110e0Safresh1then the C<undef> substitution will be performed silently.
33591f110e0Safresh1
336898184e3Ssthen=item is_shared VARIABLE
337898184e3Ssthen
338898184e3SsthenC<is_shared> checks if the specified variable is shared or not.  If shared,
339898184e3Ssthenreturns the variable's internal ID (similar to
3406fb12b70Safresh1C<refaddr()> (see L<Scalar::Util>).  Otherwise, returns C<undef>.
341898184e3Ssthen
342898184e3Ssthen  if (is_shared($var)) {
343898184e3Ssthen      print("\$var is shared\n");
344898184e3Ssthen  } else {
345898184e3Ssthen      print("\$var is not shared\n");
346898184e3Ssthen  }
347898184e3Ssthen
348898184e3SsthenWhen used on an element of an array or hash, C<is_shared> checks if the
349898184e3Ssthenspecified element belongs to a shared array or hash.  (It does not check
350898184e3Ssthenthe contents of that element.)
351898184e3Ssthen
352898184e3Ssthen  my %hash :shared;
353898184e3Ssthen  if (is_shared(%hash)) {
354898184e3Ssthen      print("\%hash is shared\n");
355898184e3Ssthen  }
356898184e3Ssthen
357898184e3Ssthen  $hash{'elem'} = 1;
358898184e3Ssthen  if (is_shared($hash{'elem'})) {
359898184e3Ssthen      print("\$hash{'elem'} is in a shared hash\n");
360898184e3Ssthen  }
361898184e3Ssthen
362898184e3Ssthen=item lock VARIABLE
363898184e3Ssthen
364898184e3SsthenC<lock> places a B<advisory> lock on a variable until the lock goes out of
365898184e3Ssthenscope.  If the variable is locked by another thread, the C<lock> call will
366898184e3Ssthenblock until it's available.  Multiple calls to C<lock> by the same thread from
367898184e3Ssthenwithin dynamically nested scopes are safe -- the variable will remain locked
368898184e3Ssthenuntil the outermost lock on the variable goes out of scope.
369898184e3Ssthen
370898184e3SsthenC<lock> follows references exactly I<one> level:
371898184e3Ssthen
372898184e3Ssthen  my %hash :shared;
373898184e3Ssthen  my $ref = \%hash;
374898184e3Ssthen  lock($ref);           # This is equivalent to lock(%hash)
375898184e3Ssthen
376898184e3SsthenNote that you cannot explicitly unlock a variable; you can only wait for the
377898184e3Ssthenlock to go out of scope.  This is most easily accomplished by locking the
378898184e3Ssthenvariable inside a block.
379898184e3Ssthen
380898184e3Ssthen  my $var :shared;
381898184e3Ssthen  {
382898184e3Ssthen      lock($var);
383898184e3Ssthen      # $var is locked from here to the end of the block
384898184e3Ssthen      ...
385898184e3Ssthen  }
386898184e3Ssthen  # $var is now unlocked
387898184e3Ssthen
388898184e3SsthenAs locks are advisory, they do not prevent data access or modification by
389898184e3Ssthenanother thread that does not itself attempt to obtain a lock on the variable.
390898184e3Ssthen
391898184e3SsthenYou cannot lock the individual elements of a container variable:
392898184e3Ssthen
393898184e3Ssthen  my %hash :shared;
394898184e3Ssthen  $hash{'foo'} = 'bar';
395898184e3Ssthen  #lock($hash{'foo'});          # Error
396898184e3Ssthen  lock(%hash);                  # Works
397898184e3Ssthen
398898184e3SsthenIf you need more fine-grained control over shared variable access, see
399898184e3SsthenL<Thread::Semaphore>.
400898184e3Ssthen
401898184e3Ssthen=item cond_wait VARIABLE
402898184e3Ssthen
403898184e3Ssthen=item cond_wait CONDVAR, LOCKVAR
404898184e3Ssthen
405898184e3SsthenThe C<cond_wait> function takes a B<locked> variable as a parameter, unlocks
406898184e3Ssthenthe variable, and blocks until another thread does a C<cond_signal> or
407898184e3SsthenC<cond_broadcast> for that same locked variable.  The variable that
40891f110e0Safresh1C<cond_wait> blocked on is re-locked after the C<cond_wait> is satisfied.  If
409898184e3Ssthenthere are multiple threads C<cond_wait>ing on the same variable, all but one
4106fb12b70Safresh1will re-block waiting to reacquire the
4116fb12b70Safresh1lock on the variable.  (So if you're only
41291f110e0Safresh1using C<cond_wait> for synchronization, give up the lock as soon as possible).
413898184e3SsthenThe two actions of unlocking the variable and entering the blocked wait state
414898184e3Ssthenare atomic, the two actions of exiting from the blocked wait state and
415898184e3Ssthenre-locking the variable are not.
416898184e3Ssthen
417898184e3SsthenIn its second form, C<cond_wait> takes a shared, B<unlocked> variable followed
418898184e3Ssthenby a shared, B<locked> variable.  The second variable is unlocked and thread
419898184e3Ssthenexecution suspended until another thread signals the first variable.
420898184e3Ssthen
421898184e3SsthenIt is important to note that the variable can be notified even if no thread
422898184e3SsthenC<cond_signal> or C<cond_broadcast> on the variable.  It is therefore
423898184e3Ssthenimportant to check the value of the variable and go back to waiting if the
424898184e3Ssthenrequirement is not fulfilled.  For example, to pause until a shared counter
425898184e3Ssthendrops to zero:
426898184e3Ssthen
427898184e3Ssthen  { lock($counter); cond_wait($counter) until $counter == 0; }
428898184e3Ssthen
429898184e3Ssthen=item cond_timedwait VARIABLE, ABS_TIMEOUT
430898184e3Ssthen
431898184e3Ssthen=item cond_timedwait CONDVAR, ABS_TIMEOUT, LOCKVAR
432898184e3Ssthen
433898184e3SsthenIn its two-argument form, C<cond_timedwait> takes a B<locked> variable and an
43491f110e0Safresh1absolute timeout in I<epoch> seconds (see L<time() in perlfunc|perlfunc/time>
43591f110e0Safresh1for more) as parameters, unlocks the variable, and blocks until the
436898184e3Ssthentimeout is reached or another thread signals the variable.  A false value is
437898184e3Ssthenreturned if the timeout is reached, and a true value otherwise.  In either
438898184e3Ssthencase, the variable is re-locked upon return.
439898184e3Ssthen
440898184e3SsthenLike C<cond_wait>, this function may take a shared, B<locked> variable as an
441898184e3Ssthenadditional parameter; in this case the first parameter is an B<unlocked>
442898184e3Ssthencondition variable protected by a distinct lock variable.
443898184e3Ssthen
444898184e3SsthenAgain like C<cond_wait>, waking up and reacquiring the lock are not atomic,
445898184e3Ssthenand you should always check your desired condition after this function
446898184e3Ssthenreturns.  Since the timeout is an absolute value, however, it does not have to
447898184e3Ssthenbe recalculated with each pass:
448898184e3Ssthen
449898184e3Ssthen  lock($var);
450898184e3Ssthen  my $abs = time() + 15;
451898184e3Ssthen  until ($ok = desired_condition($var)) {
452898184e3Ssthen      last if !cond_timedwait($var, $abs);
453898184e3Ssthen  }
454898184e3Ssthen  # we got it if $ok, otherwise we timed out!
455898184e3Ssthen
456898184e3Ssthen=item cond_signal VARIABLE
457898184e3Ssthen
458898184e3SsthenThe C<cond_signal> function takes a B<locked> variable as a parameter and
4596fb12b70Safresh1unblocks one thread that's C<cond_wait>ing
4606fb12b70Safresh1on that variable.  If more than one
461898184e3Ssthenthread is blocked in a C<cond_wait> on that variable, only one (and which one
462898184e3Ssthenis indeterminate) will be unblocked.
463898184e3Ssthen
464898184e3SsthenIf there are no threads blocked in a C<cond_wait> on the variable, the signal
4656fb12b70Safresh1is discarded.  By always locking before
4666fb12b70Safresh1signaling, you can (with care), avoid
467898184e3Ssthensignaling before another thread has entered cond_wait().
468898184e3Ssthen
469898184e3SsthenC<cond_signal> will normally generate a warning if you attempt to use it on an
4706fb12b70Safresh1unlocked variable.  On the rare occasions
4716fb12b70Safresh1where doing this may be sensible, you
472898184e3Ssthencan suppress the warning with:
473898184e3Ssthen
474898184e3Ssthen  { no warnings 'threads'; cond_signal($foo); }
475898184e3Ssthen
476898184e3Ssthen=item cond_broadcast VARIABLE
477898184e3Ssthen
478898184e3SsthenThe C<cond_broadcast> function works similarly to C<cond_signal>.
479898184e3SsthenC<cond_broadcast>, though, will unblock B<all> the threads that are blocked in
480898184e3Ssthena C<cond_wait> on the locked variable, rather than only one.
481898184e3Ssthen
482898184e3Ssthen=back
483898184e3Ssthen
484898184e3Ssthen=head1 OBJECTS
485898184e3Ssthen
486898184e3SsthenL<threads::shared> exports a version of L<bless()|perlfunc/"bless REF"> that
487898184e3Ssthenworks on shared objects such that I<blessings> propagate across threads.
488898184e3Ssthen
489898184e3Ssthen  # Create a shared 'Foo' object
490898184e3Ssthen  my $foo :shared = shared_clone({});
491898184e3Ssthen  bless($foo, 'Foo');
492898184e3Ssthen
493898184e3Ssthen  # Create a shared 'Bar' object
494898184e3Ssthen  my $bar :shared = shared_clone({});
495898184e3Ssthen  bless($bar, 'Bar');
496898184e3Ssthen
497898184e3Ssthen  # Put 'bar' inside 'foo'
498898184e3Ssthen  $foo->{'bar'} = $bar;
499898184e3Ssthen
500898184e3Ssthen  # Rebless the objects via a thread
501898184e3Ssthen  threads->create(sub {
502898184e3Ssthen      # Rebless the outer object
503898184e3Ssthen      bless($foo, 'Yin');
504898184e3Ssthen
505898184e3Ssthen      # Cannot directly rebless the inner object
506898184e3Ssthen      #bless($foo->{'bar'}, 'Yang');
507898184e3Ssthen
508898184e3Ssthen      # Retrieve and rebless the inner object
509898184e3Ssthen      my $obj = $foo->{'bar'};
510898184e3Ssthen      bless($obj, 'Yang');
511898184e3Ssthen      $foo->{'bar'} = $obj;
512898184e3Ssthen
513898184e3Ssthen  })->join();
514898184e3Ssthen
515898184e3Ssthen  print(ref($foo),          "\n");    # Prints 'Yin'
516898184e3Ssthen  print(ref($foo->{'bar'}), "\n");    # Prints 'Yang'
517898184e3Ssthen  print(ref($bar),          "\n");    # Also prints 'Yang'
518898184e3Ssthen
519898184e3Ssthen=head1 NOTES
520898184e3Ssthen
521898184e3SsthenL<threads::shared> is designed to disable itself silently if threads are not
522898184e3Ssthenavailable.  This allows you to write modules and packages that can be used
523898184e3Ssthenin both threaded and non-threaded applications.
524898184e3Ssthen
525898184e3SsthenIf you want access to threads, you must C<use threads> before you
526898184e3SsthenC<use threads::shared>.  L<threads> will emit a warning if you use it after
527898184e3SsthenL<threads::shared>.
528898184e3Ssthen
5296fb12b70Safresh1=head1 WARNINGS
5306fb12b70Safresh1
5316fb12b70Safresh1=over 4
5326fb12b70Safresh1
5336fb12b70Safresh1=item cond_broadcast() called on unlocked variable
5346fb12b70Safresh1
5356fb12b70Safresh1=item cond_signal() called on unlocked variable
5366fb12b70Safresh1
5376fb12b70Safresh1See L</"cond_signal VARIABLE">, above.
5386fb12b70Safresh1
5396fb12b70Safresh1=back
5406fb12b70Safresh1
541898184e3Ssthen=head1 BUGS AND LIMITATIONS
542898184e3Ssthen
543898184e3SsthenWhen C<share> is used on arrays, hashes, array refs or hash refs, any data
544898184e3Ssthenthey contain will be lost.
545898184e3Ssthen
546898184e3Ssthen  my @arr = qw(foo bar baz);
547898184e3Ssthen  share(@arr);
548898184e3Ssthen  # @arr is now empty (i.e., == ());
549898184e3Ssthen
550898184e3Ssthen  # Create a 'foo' object
551898184e3Ssthen  my $foo = { 'data' => 99 };
552898184e3Ssthen  bless($foo, 'foo');
553898184e3Ssthen
554898184e3Ssthen  # Share the object
555898184e3Ssthen  share($foo);        # Contents are now wiped out
556898184e3Ssthen  print("ERROR: \$foo is empty\n")
557898184e3Ssthen      if (! exists($foo->{'data'}));
558898184e3Ssthen
559898184e3SsthenTherefore, populate such variables B<after> declaring them as shared.  (Scalar
560898184e3Ssthenand scalar refs are not affected by this problem.)
561898184e3Ssthen
562b8851fccSafresh1Blessing a shared item after it has been nested in another shared item does
563b8851fccSafresh1not propagate the blessing to the shared reference:
564b8851fccSafresh1
565b8851fccSafresh1  my $foo = &share({});
566b8851fccSafresh1  my $bar = &share({});
567b8851fccSafresh1  $bar->{foo} = $foo;
568b8851fccSafresh1  bless($foo, 'baz');   # $foo is now of class 'baz',
569b8851fccSafresh1                        # but $bar->{foo} is unblessed.
570b8851fccSafresh1
571b8851fccSafresh1Therefore, you should bless objects before sharing them.
572b8851fccSafresh1
573898184e3SsthenIt is often not wise to share an object unless the class itself has been
5749f11ffb7Safresh1written to support sharing.  For example, a shared object's destructor may
5759f11ffb7Safresh1get called multiple times, once for each thread's scope exit, or may not
5769f11ffb7Safresh1get called at all if it is embedded inside another shared object.  Another
5779f11ffb7Safresh1issue is that the contents of hash-based objects will be lost due to the
5789f11ffb7Safresh1above mentioned limitation.  See F<examples/class.pl> (in the CPAN
5799f11ffb7Safresh1distribution of this module) for how to create a class that supports object
5809f11ffb7Safresh1sharing.
581898184e3Ssthen
582898184e3SsthenDestructors may not be called on objects if those objects still exist at
583898184e3Ssthenglobal destruction time.  If the destructors must be called, make sure
584898184e3Ssthenthere are no circular references and that nothing is referencing the
5859f11ffb7Safresh1objects before the program ends.
586898184e3Ssthen
587898184e3SsthenDoes not support C<splice> on arrays.  Does not support explicitly changing
588898184e3Ssthenarray lengths via $#array -- use C<push> and C<pop> instead.
589898184e3Ssthen
590898184e3SsthenTaking references to the elements of shared arrays and hashes does not
591898184e3Ssthenautovivify the elements, and neither does slicing a shared array/hash over
592898184e3Ssthennon-existent indices/keys autovivify the elements.
593898184e3Ssthen
594898184e3SsthenC<share()> allows you to C<< share($hashref->{key}) >> and
595898184e3SsthenC<< share($arrayref->[idx]) >> without giving any error message.  But the
596898184e3SsthenC<< $hashref->{key} >> or C<< $arrayref->[idx] >> is B<not> shared, causing
597898184e3Ssthenthe error "lock can only be used on shared values" to occur when you attempt
59891f110e0Safresh1to C<< lock($hashref->{key}) >> or C<< lock($arrayref->[idx]) >> in another
599898184e3Ssthenthread.
600898184e3Ssthen
6016fb12b70Safresh1Using C<refaddr()> is unreliable for testing
602898184e3Ssthenwhether or not two shared references are equivalent (e.g., when testing for
603898184e3Ssthencircular references).  Use L<is_shared()|/"is_shared VARIABLE">, instead:
604898184e3Ssthen
605898184e3Ssthen    use threads;
606898184e3Ssthen    use threads::shared;
607898184e3Ssthen    use Scalar::Util qw(refaddr);
608898184e3Ssthen
609898184e3Ssthen    # If ref is shared, use threads::shared's internal ID.
610898184e3Ssthen    # Otherwise, use refaddr().
611898184e3Ssthen    my $addr1 = is_shared($ref1) || refaddr($ref1);
612898184e3Ssthen    my $addr2 = is_shared($ref2) || refaddr($ref2);
613898184e3Ssthen
614898184e3Ssthen    if ($addr1 == $addr2) {
615898184e3Ssthen        # The refs are equivalent
616898184e3Ssthen    }
617898184e3Ssthen
618898184e3SsthenL<each()|perlfunc/"each HASH"> does not work properly on shared references
619898184e3Ssthenembedded in shared structures.  For example:
620898184e3Ssthen
621898184e3Ssthen    my %foo :shared;
622898184e3Ssthen    $foo{'bar'} = shared_clone({'a'=>'x', 'b'=>'y', 'c'=>'z'});
623898184e3Ssthen
624898184e3Ssthen    while (my ($key, $val) = each(%{$foo{'bar'}})) {
625898184e3Ssthen        ...
626898184e3Ssthen    }
627898184e3Ssthen
628898184e3SsthenEither of the following will work instead:
629898184e3Ssthen
630898184e3Ssthen    my $ref = $foo{'bar'};
631898184e3Ssthen    while (my ($key, $val) = each(%{$ref})) {
632898184e3Ssthen        ...
633898184e3Ssthen    }
634898184e3Ssthen
635898184e3Ssthen    foreach my $key (keys(%{$foo{'bar'}})) {
636898184e3Ssthen        my $val = $foo{'bar'}{$key};
637898184e3Ssthen        ...
638898184e3Ssthen    }
639898184e3Ssthen
6406fb12b70Safresh1This module supports dual-valued variables created using C<dualvar()> from
6416fb12b70Safresh1L<Scalar::Util>.  However, while C<$!> acts
64291f110e0Safresh1like a dualvar, it is implemented as a tied SV.  To propagate its value, use
64391f110e0Safresh1the follow construct, if needed:
64491f110e0Safresh1
64591f110e0Safresh1    my $errno :shared = dualvar($!,$!);
64691f110e0Safresh1
647898184e3SsthenView existing bug reports at, and submit any new bugs, problems, patches, etc.
648898184e3Ssthento: L<http://rt.cpan.org/Public/Dist/Display.html?Name=threads-shared>
649898184e3Ssthen
650898184e3Ssthen=head1 SEE ALSO
651898184e3Ssthen
6529f11ffb7Safresh1threads::shared on MetaCPAN:
6539f11ffb7Safresh1L<https://metacpan.org/release/threads-shared>
6549f11ffb7Safresh1
6559f11ffb7Safresh1Code repository for CPAN distribution:
6569f11ffb7Safresh1L<https://github.com/Dual-Life/threads-shared>
657898184e3Ssthen
658898184e3SsthenL<threads>, L<perlthrtut>
659898184e3Ssthen
660898184e3SsthenL<http://www.perl.com/pub/a/2002/06/11/threads.html> and
661898184e3SsthenL<http://www.perl.com/pub/a/2002/09/04/threads.html>
662898184e3Ssthen
663898184e3SsthenPerl threads mailing list:
664898184e3SsthenL<http://lists.perl.org/list/ithreads.html>
665898184e3Ssthen
6669f11ffb7Safresh1Sample code in the I<examples> directory of this distribution on CPAN.
6679f11ffb7Safresh1
668898184e3Ssthen=head1 AUTHOR
669898184e3Ssthen
670898184e3SsthenArtur Bergman E<lt>sky AT crucially DOT netE<gt>
671898184e3Ssthen
672898184e3SsthenDocumentation borrowed from the old Thread.pm.
673898184e3Ssthen
674898184e3SsthenCPAN version produced by Jerry D. Hedden E<lt>jdhedden AT cpan DOT orgE<gt>.
675898184e3Ssthen
676898184e3Ssthen=head1 LICENSE
677898184e3Ssthen
678898184e3Ssthenthreads::shared is released under the same license as Perl.
679898184e3Ssthen
680898184e3Ssthen=cut
681