rake 0.9.6 → 10.0.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rake might be problematic. Click here for more details.
- data/README.rdoc +12 -0
- data/Rakefile +0 -1
- data/doc/command_line_usage.rdoc +17 -60
- data/doc/release_notes/rake-0.9.3.rdoc +23 -70
- data/lib/rake.rb +0 -1
- data/lib/rake/application.rb +23 -63
- data/lib/rake/backtrace.rb +2 -3
- data/lib/rake/contrib/ftptools.rb +2 -2
- data/lib/rake/dsl_definition.rb +0 -26
- data/lib/rake/ext/module.rb +0 -39
- data/lib/rake/ext/string.rb +1 -2
- data/lib/rake/ext/time.rb +1 -2
- data/lib/rake/file_list.rb +1 -8
- data/lib/rake/file_utils.rb +1 -1
- data/lib/rake/phony.rb +2 -4
- data/lib/rake/rake_module.rb +7 -0
- data/lib/rake/ruby182_test_unit_fix.rb +0 -0
- data/lib/rake/runtest.rb +1 -2
- data/lib/rake/task.rb +8 -9
- data/lib/rake/task_manager.rb +0 -11
- data/lib/rake/testtask.rb +1 -4
- data/lib/rake/thread_history_display.rb +4 -7
- data/lib/rake/thread_pool.rb +76 -42
- data/lib/rake/version.rb +6 -7
- data/test/helper.rb +4 -44
- data/test/test_rake_application.rb +0 -47
- data/test/test_rake_application_options.rb +6 -39
- data/test/test_rake_backtrace.rb +11 -33
- data/test/test_rake_dsl.rb +0 -37
- data/test/test_rake_file_task.rb +4 -4
- data/test/test_rake_functional.rb +8 -32
- data/test/test_rake_rake_test_loader.rb +1 -1
- data/test/test_rake_reduce_compat.rb +5 -33
- data/test/test_rake_task_manager_argument_resolution.rb +0 -5
- data/test/test_rake_task_with_arguments.rb +6 -17
- data/test/test_rake_thread_pool.rb +24 -1
- data/test/test_rake_top_level_functions.rb +0 -40
- data/test/test_thread_history_display.rb +14 -14
- metadata +3 -22
- data/doc/release_notes/rake-0.9.2.2.rdoc +0 -55
- data/doc/release_notes/rake-0.9.4.rdoc +0 -110
- data/doc/release_notes/rake-0.9.5.rdoc +0 -114
- data/doc/release_notes/rake-0.9.6.rdoc +0 -127
- data/lib/rake/classic_namespace.rb +0 -11
- data/lib/rake/contrib/sys.rb +0 -192
- data/lib/rake/gempackagetask.rb +0 -15
- data/lib/rake/private_reader.rb +0 -20
- data/lib/rake/promise.rb +0 -99
- data/lib/rake/rdoctask.rb +0 -234
- data/lib/rake/trace_output.rb +0 -19
- data/test/test_private_reader.rb +0 -42
- data/test/test_rake_rdoc_task.rb +0 -83
- data/test/test_sys.rb +0 -20
- data/test/test_trace_output.rb +0 -43
data/lib/rake/backtrace.rb
CHANGED
@@ -2,12 +2,11 @@ module Rake
|
|
2
2
|
module Backtrace
|
3
3
|
SUPPRESSED_PATHS =
|
4
4
|
RbConfig::CONFIG.values_at(*RbConfig::CONFIG.
|
5
|
-
keys.grep(/(prefix|libdir)/))
|
5
|
+
keys.grep(/(prefix|libdir)/)) + [
|
6
6
|
File.join(File.dirname(__FILE__), ".."),
|
7
7
|
].map { |f| Regexp.quote(File.expand_path(f)) }
|
8
|
-
SUPPRESSED_PATHS.reject! { |s| s.nil? || s =~ /^ *$/ }
|
9
8
|
|
10
|
-
SUPPRESS_PATTERN = %r!(\A#{SUPPRESSED_PATHS.join('|')}|bin/rake:\d+)!
|
9
|
+
SUPPRESS_PATTERN = %r!(\A#{SUPPRESSED_PATHS.join('|')}|bin/rake:\d+)!
|
11
10
|
|
12
11
|
def self.collapse(backtrace)
|
13
12
|
pattern = Rake.application.options.suppress_backtrace_pattern ||
|
@@ -5,7 +5,6 @@
|
|
5
5
|
|
6
6
|
require 'date'
|
7
7
|
require 'net/ftp'
|
8
|
-
require 'rake/file_list'
|
9
8
|
|
10
9
|
module Rake # :nodoc:
|
11
10
|
|
@@ -128,7 +127,8 @@ module Rake # :nodoc:
|
|
128
127
|
# Upload all files matching +wildcard+ to the uploader's root
|
129
128
|
# path.
|
130
129
|
def upload_files(wildcard)
|
131
|
-
|
130
|
+
fail "OUCH"
|
131
|
+
Rake.glob(wildcard).each do |fn|
|
132
132
|
upload(fn)
|
133
133
|
end
|
134
134
|
end
|
data/lib/rake/dsl_definition.rb
CHANGED
@@ -32,7 +32,6 @@ module Rake
|
|
32
32
|
Rake::Task.define_task(*args, &block)
|
33
33
|
end
|
34
34
|
|
35
|
-
|
36
35
|
# Declare a file task.
|
37
36
|
#
|
38
37
|
# Example:
|
@@ -147,31 +146,7 @@ module Rake
|
|
147
146
|
Rake.application.add_import(fn)
|
148
147
|
end
|
149
148
|
end
|
150
|
-
|
151
149
|
end
|
152
|
-
|
153
|
-
DeprecatedCommands = Object.new.extend(DSL)
|
154
|
-
|
155
|
-
module DeprecatedObjectDSL # :nodoc:
|
156
|
-
DSL.private_instance_methods(false).each do |name|
|
157
|
-
line = __LINE__+1
|
158
|
-
class_eval %{
|
159
|
-
def #{name}(*args, &block)
|
160
|
-
unless Rake.application.options.ignore_deprecate
|
161
|
-
unless @rake_dsl_warning
|
162
|
-
$stderr.puts "WARNING: Global access to Rake DSL methods is deprecated. Please include"
|
163
|
-
$stderr.puts " ... Rake::DSL into classes and modules which use the Rake DSL methods."
|
164
|
-
@rake_dsl_warning = true
|
165
|
-
end
|
166
|
-
$stderr.puts "WARNING: DSL method \#{self.class}##{name} called at \#{caller.first}"
|
167
|
-
end
|
168
|
-
Rake::DeprecatedCommands.send(:#{name}, *args, &block)
|
169
|
-
end
|
170
|
-
private :#{name}
|
171
|
-
}, __FILE__, line
|
172
|
-
end
|
173
|
-
end unless defined? Rake::REDUCE_COMPAT
|
174
|
-
|
175
150
|
extend FileUtilsExt
|
176
151
|
end
|
177
152
|
|
@@ -179,4 +154,3 @@ end
|
|
179
154
|
# calls to task, etc. to work from a Rakefile without polluting the
|
180
155
|
# object inheritance tree.
|
181
156
|
self.extend Rake::DSL
|
182
|
-
include Rake::DeprecatedObjectDSL unless defined? Rake::REDUCE_COMPAT
|
data/lib/rake/ext/module.rb
CHANGED
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'rake/ext/core'
|
2
|
-
require 'rake/task'
|
3
|
-
require 'rake/file_task'
|
4
|
-
require 'rake/file_creation_task'
|
5
|
-
require 'rake/application'
|
6
|
-
require 'rake/task_manager'
|
7
|
-
|
8
|
-
######################################################################
|
9
|
-
# Rake extensions to Module.
|
10
|
-
#
|
11
|
-
class Module
|
12
|
-
|
13
|
-
# Rename the original handler to make it available.
|
14
|
-
alias :rake_original_const_missing :const_missing
|
15
|
-
|
16
|
-
# Check for deprecated uses of top level (i.e. in Object) uses of
|
17
|
-
# Rake class names. If someone tries to reference the constant
|
18
|
-
# name, display a warning and return the proper object. Using the
|
19
|
-
# --classic-namespace command line option will define these
|
20
|
-
# constants in Object and avoid this handler.
|
21
|
-
def const_missing(const_name)
|
22
|
-
case const_name
|
23
|
-
when :Task
|
24
|
-
Rake.application.const_warning(const_name)
|
25
|
-
Rake::Task
|
26
|
-
when :FileTask
|
27
|
-
Rake.application.const_warning(const_name)
|
28
|
-
Rake::FileTask
|
29
|
-
when :FileCreationTask
|
30
|
-
Rake.application.const_warning(const_name)
|
31
|
-
Rake::FileCreationTask
|
32
|
-
when :RakeApp
|
33
|
-
Rake.application.const_warning(const_name)
|
34
|
-
Rake::Application
|
35
|
-
else
|
36
|
-
rake_original_const_missing(const_name)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end unless defined? Rake::REDUCE_COMPAT
|
data/lib/rake/ext/string.rb
CHANGED
@@ -4,7 +4,6 @@ require 'rake/ext/core'
|
|
4
4
|
# Rake extension methods for String.
|
5
5
|
#
|
6
6
|
class String
|
7
|
-
|
8
7
|
rake_extension("ext") do
|
9
8
|
# Replace the file extension with +newext+. If there is no extension on
|
10
9
|
# the string, append the new extension to the end. If the new extension
|
@@ -164,5 +163,5 @@ class String
|
|
164
163
|
result
|
165
164
|
end
|
166
165
|
end
|
166
|
+
end # class String
|
167
167
|
|
168
|
-
end
|
data/lib/rake/ext/time.rb
CHANGED
data/lib/rake/file_list.rb
CHANGED
@@ -340,7 +340,7 @@ module Rake
|
|
340
340
|
|
341
341
|
# Add matching glob patterns.
|
342
342
|
def add_matching(pattern)
|
343
|
-
|
343
|
+
Rake.glob(pattern).each do |fn|
|
344
344
|
self << fn unless exclude?(fn)
|
345
345
|
end
|
346
346
|
end
|
@@ -383,13 +383,6 @@ module Rake
|
|
383
383
|
def [](*args)
|
384
384
|
new(*args)
|
385
385
|
end
|
386
|
-
|
387
|
-
# Get a sorted list of files matching the pattern. This method
|
388
|
-
# should be prefered to Dir[pattern] and Dir.glob(pattern) because
|
389
|
-
# the files returned are guaranteed to be sorted.
|
390
|
-
def glob(pattern, *args)
|
391
|
-
Dir.glob(pattern, *args).sort
|
392
|
-
end
|
393
386
|
end
|
394
387
|
end
|
395
388
|
end
|
data/lib/rake/file_utils.rb
CHANGED
@@ -6,7 +6,7 @@ require 'fileutils'
|
|
6
6
|
# added to the FileUtils utility functions.
|
7
7
|
module FileUtils
|
8
8
|
# Path to the currently running Ruby program
|
9
|
-
RUBY =
|
9
|
+
RUBY = File.join(
|
10
10
|
RbConfig::CONFIG['bindir'],
|
11
11
|
RbConfig::CONFIG['ruby_install_name'] + RbConfig::CONFIG['EXEEXT']).
|
12
12
|
sub(/.*\s.*/m, '"\&"')
|
data/lib/rake/phony.rb
CHANGED
data/lib/rake/rake_module.rb
CHANGED
@@ -32,6 +32,13 @@ module Rake
|
|
32
32
|
application.options.rakelib << file
|
33
33
|
end
|
34
34
|
end
|
35
|
+
|
36
|
+
# Get a sorted list of files matching the pattern. This method
|
37
|
+
# should be prefered to Dir[pattern] and Dir.glob[pattern] because
|
38
|
+
# the files returned are guaranteed to be sorted.
|
39
|
+
def glob(pattern, *args)
|
40
|
+
Dir.glob(pattern, *args).sort
|
41
|
+
end
|
35
42
|
end
|
36
43
|
|
37
44
|
end
|
File without changes
|
data/lib/rake/runtest.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require 'test/unit/assertions'
|
3
|
-
require 'rake/file_list'
|
4
3
|
|
5
4
|
module Rake
|
6
5
|
include Test::Unit::Assertions
|
7
6
|
|
8
7
|
def run_tests(pattern='test/test*.rb', log_enabled=false)
|
9
|
-
|
8
|
+
Rake.glob(pattern).each { |fn|
|
10
9
|
$stderr.puts fn if log_enabled
|
11
10
|
begin
|
12
11
|
require fn
|
data/lib/rake/task.rb
CHANGED
@@ -105,7 +105,7 @@ module Rake
|
|
105
105
|
|
106
106
|
# Argument description (nil if none).
|
107
107
|
def arg_description # :nodoc:
|
108
|
-
@arg_names ? "[#{arg_names.join(',')}]" : nil
|
108
|
+
@arg_names ? "[#{(arg_names || []).join(',')}]" : nil
|
109
109
|
end
|
110
110
|
|
111
111
|
# Name of arguments for this task.
|
@@ -182,22 +182,21 @@ module Rake
|
|
182
182
|
if application.options.always_multitask
|
183
183
|
invoke_prerequisites_concurrently(task_args, invocation_chain)
|
184
184
|
else
|
185
|
-
prerequisite_tasks.each { |
|
186
|
-
prereq_args = task_args.new_scope(
|
187
|
-
|
185
|
+
prerequisite_tasks.each { |prereq|
|
186
|
+
prereq_args = task_args.new_scope(prereq.arg_names)
|
187
|
+
prereq.invoke_with_call_chain(prereq_args, invocation_chain)
|
188
188
|
}
|
189
189
|
end
|
190
190
|
end
|
191
191
|
|
192
192
|
# Invoke all the prerequisites of a task in parallel.
|
193
|
-
def invoke_prerequisites_concurrently(
|
194
|
-
futures =
|
195
|
-
prereq_args = task_args.new_scope(p.arg_names)
|
193
|
+
def invoke_prerequisites_concurrently(args, invocation_chain) # :nodoc:
|
194
|
+
futures = @prerequisites.collect do |p|
|
196
195
|
application.thread_pool.future(p) do |r|
|
197
|
-
r.invoke_with_call_chain(
|
196
|
+
application[r, @scope].invoke_with_call_chain(args, invocation_chain)
|
198
197
|
end
|
199
198
|
end
|
200
|
-
futures.each { |f| f.
|
199
|
+
futures.each { |f| f.call }
|
201
200
|
end
|
202
201
|
|
203
202
|
# Format the trace flags for display.
|
data/lib/rake/task_manager.rb
CHANGED
@@ -72,7 +72,6 @@ module Rake
|
|
72
72
|
#
|
73
73
|
# task :t
|
74
74
|
# task :t, [:a]
|
75
|
-
# task :t, :a (deprecated)
|
76
75
|
#
|
77
76
|
def resolve_args_without_dependencies(args)
|
78
77
|
task_name = args.shift
|
@@ -92,8 +91,6 @@ module Rake
|
|
92
91
|
#
|
93
92
|
# task :t => [:d]
|
94
93
|
# task :t, [a] => [:d]
|
95
|
-
# task :t, :needs => [:d] (deprecated)
|
96
|
-
# task :t, :a, :needs => [:d] (deprecated)
|
97
94
|
#
|
98
95
|
def resolve_args_with_dependencies(args, hash) # :nodoc:
|
99
96
|
fail "Task Argument Error" if hash.size != 1
|
@@ -102,14 +99,6 @@ module Rake
|
|
102
99
|
task_name = key
|
103
100
|
arg_names = []
|
104
101
|
deps = value
|
105
|
-
elsif key == :needs
|
106
|
-
Rake.application.deprecate(
|
107
|
-
"task :t, arg, :needs => [deps]",
|
108
|
-
"task :t, [args] => [deps]",
|
109
|
-
caller.detect { |c| c !~ /\blib\/rake\b/ })
|
110
|
-
task_name = args.shift
|
111
|
-
arg_names = args
|
112
|
-
deps = value
|
113
102
|
else
|
114
103
|
task_name = args.shift
|
115
104
|
arg_names = key
|
data/lib/rake/testtask.rb
CHANGED
@@ -96,12 +96,9 @@ module Rake
|
|
96
96
|
desc "Run tests" + (@name==:test ? "" : " for #{@name}")
|
97
97
|
task @name do
|
98
98
|
FileUtilsExt.verbose(@verbose) do
|
99
|
-
|
100
|
-
ruby args do |ok, status|
|
99
|
+
ruby "#{ruby_opts_string} #{run_code} #{file_list_string} #{option_list}" do |ok, status|
|
101
100
|
if !ok && status.respond_to?(:signaled?) && status.signaled?
|
102
101
|
raise SignalException.new(status.termsig)
|
103
|
-
elsif !ok
|
104
|
-
fail "Command failed with status (#{status.exitstatus}): [ruby #{args}]"
|
105
102
|
end
|
106
103
|
end
|
107
104
|
end
|
@@ -1,11 +1,8 @@
|
|
1
|
-
require 'rake/private_reader'
|
2
|
-
|
3
1
|
module Rake
|
4
2
|
|
5
|
-
class ThreadHistoryDisplay
|
6
|
-
|
7
|
-
|
8
|
-
private_reader :stats, :items, :threads
|
3
|
+
class ThreadHistoryDisplay
|
4
|
+
attr_reader :stats, :items, :threads
|
5
|
+
private :stats, :items, :threads
|
9
6
|
|
10
7
|
def initialize(stats)
|
11
8
|
@stats = stats
|
@@ -16,7 +13,7 @@ module Rake
|
|
16
13
|
def show
|
17
14
|
puts "Job History:"
|
18
15
|
stats.each do |stat|
|
19
|
-
stat[:data] ||=
|
16
|
+
stat[:data] ||= []
|
20
17
|
rename(stat, :thread, threads)
|
21
18
|
rename(stat[:data], :item_id, items)
|
22
19
|
rename(stat[:data], :new_thread, threads)
|
data/lib/rake/thread_pool.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
require 'thread'
|
2
2
|
require 'set'
|
3
3
|
|
4
|
-
require 'rake/promise'
|
5
|
-
|
6
4
|
module Rake
|
7
5
|
|
8
6
|
class ThreadPool # :nodoc: all
|
@@ -30,12 +28,63 @@ module Rake
|
|
30
28
|
# pool. Sending <tt>#value</tt> to the object will sleep the
|
31
29
|
# current thread until the future is finished and will return the
|
32
30
|
# result (or raise an exception thrown from the future)
|
33
|
-
def future(*args
|
34
|
-
|
35
|
-
|
31
|
+
def future(*args,&block)
|
32
|
+
# capture the local args for the block (like Thread#start)
|
33
|
+
local_args = args.collect { |a| begin; a.dup; rescue; a; end }
|
34
|
+
|
35
|
+
promise_mutex = Mutex.new
|
36
|
+
promise_result = promise_error = NOT_SET
|
37
|
+
|
38
|
+
# (promise code builds on Ben Lavender's public-domain 'promise' gem)
|
39
|
+
promise = lambda do
|
40
|
+
# return immediately if the future has been executed
|
41
|
+
unless promise_result.equal?(NOT_SET) && promise_error.equal?(NOT_SET)
|
42
|
+
return promise_error.equal?(NOT_SET) ? promise_result : raise(promise_error)
|
43
|
+
end
|
44
|
+
|
45
|
+
# try to get the lock and execute the promise, otherwise, sleep.
|
46
|
+
if promise_mutex.try_lock
|
47
|
+
if promise_result.equal?(NOT_SET) && promise_error.equal?(NOT_SET)
|
48
|
+
#execute the promise
|
49
|
+
begin
|
50
|
+
promise_result = block.call(*local_args)
|
51
|
+
rescue Exception => e
|
52
|
+
promise_error = e
|
53
|
+
end
|
54
|
+
block = local_args = nil # GC can now clean these up
|
55
|
+
end
|
56
|
+
promise_mutex.unlock
|
57
|
+
else
|
58
|
+
# Even if we didn't get the lock, we need to sleep until the
|
59
|
+
# promise has finished executing. If, however, the current
|
60
|
+
# thread is part of the thread pool, we need to free up a
|
61
|
+
# new thread in the pool so there will always be a thread
|
62
|
+
# doing work.
|
63
|
+
|
64
|
+
wait_for_promise = lambda {
|
65
|
+
stat :waiting, item_id: promise.object_id
|
66
|
+
promise_mutex.synchronize {}
|
67
|
+
stat :continue, item_id: promise.object_id
|
68
|
+
}
|
69
|
+
|
70
|
+
unless @threads_mon.synchronize { @threads.include? Thread.current }
|
71
|
+
wait_for_promise.call
|
72
|
+
else
|
73
|
+
@threads_mon.synchronize { @max_active_threads += 1 }
|
74
|
+
start_thread
|
75
|
+
wait_for_promise.call
|
76
|
+
@threads_mon.synchronize { @max_active_threads -= 1 }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
promise_error.equal?(NOT_SET) ? promise_result : raise(promise_error)
|
80
|
+
end
|
81
|
+
|
82
|
+
def promise.value
|
83
|
+
call
|
84
|
+
end
|
36
85
|
|
37
86
|
@queue.enq promise
|
38
|
-
stat :
|
87
|
+
stat :item_queued, item_id: promise.object_id
|
39
88
|
start_thread
|
40
89
|
promise
|
41
90
|
end
|
@@ -44,18 +93,14 @@ module Rake
|
|
44
93
|
def join
|
45
94
|
@threads_mon.synchronize do
|
46
95
|
begin
|
47
|
-
|
48
|
-
@join_cond.wait unless @threads.empty?
|
49
|
-
stat :joined
|
96
|
+
@join_cond.wait unless @threads.empty?
|
50
97
|
rescue Exception => e
|
51
|
-
stat :joined
|
52
98
|
$stderr.puts e
|
53
99
|
$stderr.print "Queue contains #{@queue.size} items. Thread pool contains #{@threads.count} threads\n"
|
54
100
|
$stderr.print "Current Thread #{Thread.current} status = #{Thread.current.status}\n"
|
55
101
|
$stderr.puts e.backtrace.join("\n")
|
56
102
|
@threads.each do |t|
|
57
103
|
$stderr.print "Thread #{t} status = #{t.status}\n"
|
58
|
-
# 1.8 doesn't support Thread#backtrace
|
59
104
|
$stderr.puts t.backtrace.join("\n") if t.respond_to? :backtrace
|
60
105
|
end
|
61
106
|
raise e
|
@@ -74,58 +119,45 @@ module Rake
|
|
74
119
|
# (see #gather_history). Best to call this when the job is
|
75
120
|
# complete (i.e. after ThreadPool#join is called).
|
76
121
|
def history # :nodoc:
|
77
|
-
@history_mon.synchronize { @history.dup }
|
78
|
-
sort_by { |i| i[:time] }.
|
79
|
-
each { |i| i[:time] -= @history_start_time }
|
122
|
+
@history_mon.synchronize { @history.dup }
|
80
123
|
end
|
81
124
|
|
82
125
|
# Return a hash of always collected statistics for the thread pool.
|
83
126
|
def statistics # :nodoc:
|
84
127
|
{
|
85
|
-
:
|
86
|
-
:
|
128
|
+
total_threads_in_play: @total_threads_in_play,
|
129
|
+
max_active_threads: @max_active_threads,
|
87
130
|
}
|
88
131
|
end
|
89
132
|
|
90
133
|
private
|
91
134
|
|
92
|
-
# processes one item on the queue. Returns true if there was an
|
93
|
-
# item to process, false if there was no item
|
94
|
-
def process_queue_item #:nodoc:
|
95
|
-
return false if @queue.empty?
|
96
|
-
|
97
|
-
# Even though we just asked if the queue was empty, it
|
98
|
-
# still could have had an item which by this statement
|
99
|
-
# is now gone. For this reason we pass true to Queue#deq
|
100
|
-
# because we will sleep indefinitely if it is empty.
|
101
|
-
promise = @queue.deq(true)
|
102
|
-
stat :dequeued, :item_id => promise.object_id
|
103
|
-
promise.work
|
104
|
-
return true
|
105
|
-
|
106
|
-
rescue ThreadError # this means the queue is empty
|
107
|
-
false
|
108
|
-
end
|
109
|
-
|
110
135
|
def start_thread # :nodoc:
|
111
136
|
@threads_mon.synchronize do
|
112
137
|
next unless @threads.count < @max_active_threads
|
113
138
|
|
114
139
|
t = Thread.new do
|
115
140
|
begin
|
116
|
-
while @threads.count <= @max_active_threads
|
117
|
-
|
141
|
+
while @threads.count <= @max_active_threads && !@queue.empty? do
|
142
|
+
# Even though we just asked if the queue was empty, it
|
143
|
+
# still could have had an item which by this statement
|
144
|
+
# is now gone. For this reason we pass true to Queue#deq
|
145
|
+
# because we will sleep indefinitely if it is empty.
|
146
|
+
block = @queue.deq(true)
|
147
|
+
stat :item_dequeued, item_id: block.object_id
|
148
|
+
block.call
|
118
149
|
end
|
150
|
+
rescue ThreadError # this means the queue is empty
|
119
151
|
ensure
|
120
152
|
@threads_mon.synchronize do
|
121
153
|
@threads.delete Thread.current
|
122
|
-
stat :
|
154
|
+
stat :thread_deleted, deleted_thread: Thread.current.object_id, thread_count: @threads.count
|
123
155
|
@join_cond.broadcast if @threads.empty?
|
124
156
|
end
|
125
157
|
end
|
126
158
|
end
|
127
159
|
@threads << t
|
128
|
-
stat :
|
160
|
+
stat :thread_created, new_thread: t.object_id, thread_count: @threads.count
|
129
161
|
@total_threads_in_play = @threads.count if @threads.count > @total_threads_in_play
|
130
162
|
end
|
131
163
|
end
|
@@ -133,10 +165,10 @@ module Rake
|
|
133
165
|
def stat(event, data=nil) # :nodoc:
|
134
166
|
return if @history_start_time.nil?
|
135
167
|
info = {
|
136
|
-
:
|
137
|
-
:
|
138
|
-
:
|
139
|
-
:
|
168
|
+
event: event,
|
169
|
+
data: data,
|
170
|
+
time: (Time.now-@history_start_time),
|
171
|
+
thread: Thread.current.object_id,
|
140
172
|
}
|
141
173
|
@history_mon.synchronize { @history << info }
|
142
174
|
end
|
@@ -150,6 +182,8 @@ module Rake
|
|
150
182
|
def __threads__ # :nodoc:
|
151
183
|
@threads.dup
|
152
184
|
end
|
185
|
+
|
186
|
+
NOT_SET = Object.new.freeze # :nodoc:
|
153
187
|
end
|
154
188
|
|
155
189
|
end
|