File Coverage

blib/lib/Thread/Isolate/Pool.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             #############################################################################
2             ## Name: Pool.pm
3             ## Purpose: Thread::Isolate::Pool
4             ## Author: Graciliano M. P.
5             ## Modified by:
6             ## Created: 2005-01-29
7             ## RCS-ID:
8             ## Copyright: (c) 2005 Graciliano M. P.
9             ## Licence: This program is free software; you can redistribute it and/or
10             ## modify it under the same terms as Perl itself
11             #############################################################################
12              
13             package Thread::Isolate::Pool ;
14              
15 1     1   8302 use strict qw(vars) ;
  1         3  
  1         43  
16 1     1   8 no warnings ;
  1         2  
  1         47  
17              
18 1     1   1985 use Thread::Isolate ;
  0            
  0            
19              
20             #######
21             # NEW #
22             #######
23              
24             sub new {
25             my $this = shift ;
26             return( $this ) if ref($this) ;
27             my $class = $this || __PACKAGE__ ;
28            
29             my $limit = shift ;
30              
31             my $pool = Thread::Isolate::Thread::share_new_ref('@') ;
32            
33             my $main_thr = Thread::Isolate->new() ;
34             $main_thr->{clone} = 1 ;
35            
36             $$pool[0] = $limit || 0 ;
37             $$pool[1] = $main_thr ;
38              
39             $this = bless($pool , $class) ;
40              
41             return $this ;
42             }
43              
44             ########
45             # COPY #
46             ########
47              
48             sub copy {
49             my $this = shift ;
50            
51             my $pool = Thread::Isolate::Thread::share_new_ref('@') ;
52            
53             my $tm = $this->main_thread ;
54            
55             my $main_thr = $this->main_thread->new_internal ;
56             $main_thr->{clone} = 1 ;
57            
58             $$pool[0] = $$this[0] ;
59             $$pool[1] = $main_thr ;
60              
61             return bless($pool , ref($this)) ;
62             }
63              
64             ###############
65             # MAIN_THREAD #
66             ###############
67              
68             sub main_thread {
69             my $this = shift ;
70             return $this->[1] ;
71             }
72              
73             #########
74             # LIMIT #
75             #########
76              
77             sub limit {
78             my $this = shift ;
79             return $this->[0] ;
80             }
81              
82             ###########
83             # THREADS #
84             ###########
85              
86             sub threads {
87             my $this = shift ;
88            
89             { lock( @$this ) ;
90             return @$this[2 .. $#{$this}] ;
91             }
92             }
93              
94             #################
95             # THREADS_TOTAL #
96             #################
97              
98             sub threads_total {
99             my $this = shift ;
100            
101             { lock( @$this ) ;
102             return($#{$this} - 1) ;
103             }
104             }
105              
106             ##############
107             # ADD_THREAD #
108             ##############
109              
110             sub add_thread {
111             my $this = shift ;
112             return if $this->limit && $this->threads_total == $this->limit ;
113             my $th_new = $this->main_thread->new_internal ;
114             $th_new->{clone} = 1 ;
115             push(@$this , $th_new) ;
116             return $th_new ;
117             }
118              
119             ###################
120             # GET_FREE_THREAD #
121             ###################
122              
123             sub get_free_thread {
124             my $this = shift ;
125            
126             my ($th_free , $on_limit) ;
127            
128             { lock( @$this ) ;
129            
130             my @threads = $this->threads ;
131             my @threads_free ;
132            
133             foreach my $threads_i ( @threads ) {
134             if ( $threads_i && !$threads_i->is_running_any_job ) {
135             push(@threads_free , $threads_i) ;
136             }
137             }
138            
139             if ( !@threads_free ) {
140             my $new_thr = $this->add_thread() ;
141             if ( $new_thr ) {
142             push(@threads_free , $new_thr) ;
143             }
144             else {
145             ## Let's sort a thread from all if we can't create a new due LIMIT:
146             @threads_free = @threads ;
147             $on_limit = 1 ;
148             }
149             }
150            
151             $th_free = (sort { $a->{pool_use} <=> $b->{pool_use} } @threads_free)[0] ;
152            
153             ++$th_free->{pool_use} ;
154             }
155              
156             return( $th_free , $on_limit ) if wantarray ;
157             return $th_free ;
158             }
159              
160             #######
161             # USE #
162             #######
163              
164             sub use {
165             my $this = shift ;
166             return $this->main_thread->use(@_) ;
167             }
168              
169             ########
170             # EVAL #
171             ########
172              
173             sub eval_detached {
174             my $this = shift ;
175             my ($thf , $on_limit) = $this->get_free_thread ;
176             return ( $on_limit ? $thf->eval_detached_no_lock(@_) : $thf->eval_detached(@_) ) ;
177             }
178              
179             sub eval {
180             my $this = shift ;
181             my ($thf , $on_limit) = $this->get_free_thread ;
182             return ( $on_limit ? $thf->eval_no_lock(@_) : $thf->eval(@_) ) ;
183             }
184              
185             ########
186             # CALL #
187             ########
188              
189             sub call_detached {
190             my $this = shift ;
191             my ($thf , $on_limit) = $this->get_free_thread ;
192             return ( $on_limit ? $thf->call_detached_no_lock(@_) : $thf->call_detached(@_) ) ;
193             }
194              
195             sub call {
196             my $this = shift ;
197             my ($thf , $on_limit) = $this->get_free_thread ;
198             return ( $on_limit ? $thf->call_no_lock(@_) : $thf->call(@_) ) ;
199             }
200              
201             ############
202             # SHUTDOWN #
203             ############
204              
205             sub shutdown {
206             my $this = shift ;
207            
208             { lock( @$this ) ;
209            
210             my @threads = $this->threads ;
211            
212             foreach my $threads_i ( @threads ) {
213             next if !$threads_i ;
214             $threads_i->shutdown ;
215             $threads_i = undef ;
216             }
217             }
218              
219             return 1 ;
220             }
221              
222             ###########
223             # DESTROY #
224             ###########
225              
226             sub DESTROY {
227             my $this = shift ;
228             $this->shutdown ;
229             }
230              
231             #######
232             # END #
233             #######
234              
235             1;
236              
237             __END__