drake 0.8.1.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +386 -0
- data/MIT-LICENSE +21 -0
- data/README +396 -0
- data/Rakefile +505 -0
- data/TODO +20 -0
- data/bin/drake +31 -0
- data/bin/rake +31 -0
- data/doc/example/Rakefile1 +38 -0
- data/doc/example/Rakefile2 +35 -0
- data/doc/example/a.c +6 -0
- data/doc/example/b.c +6 -0
- data/doc/example/main.c +11 -0
- data/doc/glossary.rdoc +51 -0
- data/doc/jamis.rb +591 -0
- data/doc/proto_rake.rdoc +127 -0
- data/doc/rake.1.gz +0 -0
- data/doc/rakefile.rdoc +534 -0
- data/doc/rational.rdoc +151 -0
- data/doc/release_notes/rake-0.4.14.rdoc +23 -0
- data/doc/release_notes/rake-0.4.15.rdoc +35 -0
- data/doc/release_notes/rake-0.5.0.rdoc +53 -0
- data/doc/release_notes/rake-0.5.3.rdoc +78 -0
- data/doc/release_notes/rake-0.5.4.rdoc +46 -0
- data/doc/release_notes/rake-0.6.0.rdoc +141 -0
- data/doc/release_notes/rake-0.7.0.rdoc +119 -0
- data/doc/release_notes/rake-0.7.1.rdoc +59 -0
- data/doc/release_notes/rake-0.7.2.rdoc +121 -0
- data/doc/release_notes/rake-0.7.3.rdoc +47 -0
- data/doc/release_notes/rake-0.8.0.rdoc +114 -0
- data/doc/release_notes/rake-0.8.2.rdoc +163 -0
- data/install.rb +88 -0
- data/lib/rake.rb +2538 -0
- data/lib/rake/classic_namespace.rb +8 -0
- data/lib/rake/clean.rb +33 -0
- data/lib/rake/comp_tree/algorithm.rb +234 -0
- data/lib/rake/comp_tree/bucket_ipc.rb +175 -0
- data/lib/rake/comp_tree/driver.rb +291 -0
- data/lib/rake/comp_tree/error.rb +51 -0
- data/lib/rake/comp_tree/node.rb +189 -0
- data/lib/rake/comp_tree/quix/builtin/kernel/tap.rb +57 -0
- data/lib/rake/comp_tree/quix/diagnostic.rb +92 -0
- data/lib/rake/comp_tree/quix/kernel.rb +109 -0
- data/lib/rake/comp_tree/retriable_fork.rb +66 -0
- data/lib/rake/comp_tree/task_node.rb +46 -0
- data/lib/rake/contrib/compositepublisher.rb +24 -0
- data/lib/rake/contrib/ftptools.rb +153 -0
- data/lib/rake/contrib/publisher.rb +75 -0
- data/lib/rake/contrib/rubyforgepublisher.rb +18 -0
- data/lib/rake/contrib/sshpublisher.rb +47 -0
- data/lib/rake/contrib/sys.rb +209 -0
- data/lib/rake/gempackagetask.rb +103 -0
- data/lib/rake/loaders/makefile.rb +35 -0
- data/lib/rake/packagetask.rb +185 -0
- data/lib/rake/parallel.rb +54 -0
- data/lib/rake/rake_test_loader.rb +5 -0
- data/lib/rake/rdoctask.rb +147 -0
- data/lib/rake/ruby182_test_unit_fix.rb +23 -0
- data/lib/rake/runtest.rb +23 -0
- data/lib/rake/tasklib.rb +23 -0
- data/lib/rake/testtask.rb +161 -0
- data/test/capture_stdout.rb +26 -0
- data/test/check_expansion.rb +5 -0
- data/test/contrib/test_sys.rb +47 -0
- data/test/data/chains/Rakefile +15 -0
- data/test/data/default/Rakefile +19 -0
- data/test/data/dryrun/Rakefile +22 -0
- data/test/data/file_creation_task/Rakefile +33 -0
- data/test/data/imports/Rakefile +19 -0
- data/test/data/imports/deps.mf +1 -0
- data/test/data/multidesc/Rakefile +17 -0
- data/test/data/namespace/Rakefile +57 -0
- data/test/data/rakelib/test1.rb +3 -0
- data/test/data/rbext/rakefile.rb +3 -0
- data/test/data/sample.mf +12 -0
- data/test/data/statusreturn/Rakefile +8 -0
- data/test/data/unittest/Rakefile +1 -0
- data/test/filecreation.rb +32 -0
- data/test/functional.rb +15 -0
- data/test/in_environment.rb +30 -0
- data/test/parallel.rb +3 -0
- data/test/rake_test_setup.rb +5 -0
- data/test/reqfile.rb +3 -0
- data/test/reqfile2.rb +3 -0
- data/test/session_functional.rb +324 -0
- data/test/shellcommand.rb +3 -0
- data/test/single_threaded.rb +2 -0
- data/test/test_application.rb +714 -0
- data/test/test_clean.rb +14 -0
- data/test/test_definitions.rb +82 -0
- data/test/test_earlytime.rb +35 -0
- data/test/test_extension.rb +63 -0
- data/test/test_file_creation_task.rb +62 -0
- data/test/test_file_task.rb +139 -0
- data/test/test_filelist.rb +618 -0
- data/test/test_fileutils.rb +250 -0
- data/test/test_ftp.rb +59 -0
- data/test/test_invocation_chain.rb +75 -0
- data/test/test_makefile_loader.rb +25 -0
- data/test/test_namespace.rb +36 -0
- data/test/test_package_task.rb +116 -0
- data/test/test_parallel.rb +47 -0
- data/test/test_pathmap.rb +209 -0
- data/test/test_rake.rb +41 -0
- data/test/test_require.rb +33 -0
- data/test/test_rules.rb +348 -0
- data/test/test_task_arguments.rb +89 -0
- data/test/test_task_manager.rb +172 -0
- data/test/test_tasklib.rb +12 -0
- data/test/test_tasks.rb +373 -0
- data/test/test_test_task.rb +75 -0
- data/test/test_top_level_functions.rb +84 -0
- metadata +190 -0
@@ -0,0 +1,291 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
|
4
|
+
######################################################
|
5
|
+
#
|
6
|
+
# **** DO NOT EDIT ****
|
7
|
+
#
|
8
|
+
# **** THIS IS A GENERATED FILE *****
|
9
|
+
#
|
10
|
+
######################################################
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
require 'rake/comp_tree/bucket_ipc'
|
15
|
+
require 'rake/comp_tree/quix/diagnostic'
|
16
|
+
require 'rake/comp_tree/quix/kernel'
|
17
|
+
require 'rake/comp_tree/algorithm'
|
18
|
+
require 'rake/comp_tree/node'
|
19
|
+
require 'rake/comp_tree/task_node'
|
20
|
+
require 'rake/comp_tree/error'
|
21
|
+
|
22
|
+
require 'thread'
|
23
|
+
|
24
|
+
module Rake::CompTree
|
25
|
+
#
|
26
|
+
# Driver is the main interface to the computation tree. It is
|
27
|
+
# responsible for defining nodes and running computations.
|
28
|
+
#
|
29
|
+
class Driver
|
30
|
+
DEFAULTS = {
|
31
|
+
:threads => 1,
|
32
|
+
:fork => false,
|
33
|
+
:timeout => 5.0,
|
34
|
+
:wait_interval => 0.02,
|
35
|
+
}
|
36
|
+
|
37
|
+
include Quix::Diagnostic #:nodoc:
|
38
|
+
include Quix::Kernel #:nodoc:
|
39
|
+
|
40
|
+
#
|
41
|
+
# Begin a new computation tree.
|
42
|
+
#
|
43
|
+
# Options hash:
|
44
|
+
#
|
45
|
+
# <tt>:node_class</tt> -- (Class) Rake::CompTree::Node subclass from
|
46
|
+
# which nodes are created.
|
47
|
+
#
|
48
|
+
# <tt>:discard_result</tt> -- (boolean) If you are <em>not</em>
|
49
|
+
# interested in the final answer, but only in the actions which
|
50
|
+
# complete the computation, then set this to +true+. This is
|
51
|
+
# equivalent to saying <tt>:node_class => Rake::CompTree::TaskNode</tt>.
|
52
|
+
# (If you are forking processes, it is good to know that IPC is
|
53
|
+
# not needed to communicate the result.)
|
54
|
+
#
|
55
|
+
def initialize(opts = nil)
|
56
|
+
if opts and opts[:node_class] and opts[:discard_result]
|
57
|
+
raise(
|
58
|
+
Error::ArgumentError,
|
59
|
+
"#{self.class.name}.new: :discard_result and :node_class " +
|
60
|
+
"are mutually exclusive")
|
61
|
+
end
|
62
|
+
|
63
|
+
@node_class =
|
64
|
+
if opts and opts[:node_class]
|
65
|
+
opts[:node_class]
|
66
|
+
elsif opts and opts[:discard_result]
|
67
|
+
TaskNode
|
68
|
+
else
|
69
|
+
Node
|
70
|
+
end
|
71
|
+
|
72
|
+
@nodes = Hash.new
|
73
|
+
|
74
|
+
if block_given?
|
75
|
+
yield self
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
# Name-to-node hash.
|
81
|
+
#
|
82
|
+
attr_reader :nodes
|
83
|
+
|
84
|
+
#
|
85
|
+
# Define a computation node.
|
86
|
+
#
|
87
|
+
# There are three distinct forms of a node definition. In each of
|
88
|
+
# the following examples, a computation node named +area+ is
|
89
|
+
# defined which depends on the nodes +height+, +width+, +offset+.
|
90
|
+
#
|
91
|
+
# The method_missing form:
|
92
|
+
# driver.define_area(:width, :height, :offset) { |width, height, offset|
|
93
|
+
# width*height - offset
|
94
|
+
# }
|
95
|
+
#
|
96
|
+
# The eval form:
|
97
|
+
# driver.define_area :width, :height, :offset, %{
|
98
|
+
# width*height - offset
|
99
|
+
# }
|
100
|
+
# Note the '%' before the brace. The eval form creates a lambda for you.
|
101
|
+
#
|
102
|
+
# The raw form:
|
103
|
+
# driver.define(:area, :width, :height, :offset) { |width, height, offset|
|
104
|
+
# width*height - offset
|
105
|
+
# }
|
106
|
+
#
|
107
|
+
def define(*args, &block)
|
108
|
+
parent_name = args.first
|
109
|
+
children_names = args[1..-1]
|
110
|
+
|
111
|
+
unless parent_name
|
112
|
+
raise Error::ArgumentError, "No name given for node"
|
113
|
+
end
|
114
|
+
|
115
|
+
#
|
116
|
+
# retrieve or create parent and children
|
117
|
+
#
|
118
|
+
parent =
|
119
|
+
if t = @nodes[parent_name]
|
120
|
+
t
|
121
|
+
else
|
122
|
+
@nodes[parent_name] = @node_class.new(parent_name)
|
123
|
+
end
|
124
|
+
|
125
|
+
if parent.function
|
126
|
+
raise Error::RedefinitionError, "Node #{parent.name} already defined."
|
127
|
+
end
|
128
|
+
parent.function = block
|
129
|
+
|
130
|
+
children = children_names.map { |child_name|
|
131
|
+
if t = @nodes[child_name]
|
132
|
+
t
|
133
|
+
else
|
134
|
+
@nodes[child_name] = @node_class.new(child_name)
|
135
|
+
end
|
136
|
+
}
|
137
|
+
|
138
|
+
#
|
139
|
+
# link
|
140
|
+
#
|
141
|
+
parent.children = children
|
142
|
+
children.each { |child|
|
143
|
+
child.parents << parent
|
144
|
+
}
|
145
|
+
end
|
146
|
+
|
147
|
+
#
|
148
|
+
# parsing/evaling helper
|
149
|
+
#
|
150
|
+
def evaling_define(*args) #:nodoc:
|
151
|
+
function_name = args[0]
|
152
|
+
function_arg_names = args[1..-2]
|
153
|
+
function_string = args.last.to_str
|
154
|
+
|
155
|
+
comma_separated = function_arg_names.map { |name|
|
156
|
+
name.to_s
|
157
|
+
}.join(",")
|
158
|
+
|
159
|
+
eval_me = %{
|
160
|
+
lambda { |#{comma_separated}|
|
161
|
+
#{function_string}
|
162
|
+
}
|
163
|
+
}
|
164
|
+
|
165
|
+
function = eval(eval_me, TOPLEVEL_BINDING)
|
166
|
+
|
167
|
+
define(function_name, *function_arg_names, &function)
|
168
|
+
end
|
169
|
+
|
170
|
+
def method_missing(symbol, *args, &block) #:nodoc:
|
171
|
+
if match = symbol.to_s.match(%r!\Adefine_(\w+)\Z!)
|
172
|
+
method_name = match.captures.first.to_sym
|
173
|
+
if block
|
174
|
+
define(method_name, *args, &block)
|
175
|
+
else
|
176
|
+
evaling_define(method_name, *args)
|
177
|
+
end
|
178
|
+
else
|
179
|
+
super(symbol, *args, &block)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
#
|
184
|
+
# Mark this node and all its children as uncomputed.
|
185
|
+
#
|
186
|
+
# Arguments:
|
187
|
+
#
|
188
|
+
# +name+ -- (Symbol) node name.
|
189
|
+
#
|
190
|
+
def reset(name)
|
191
|
+
@nodes[name].reset
|
192
|
+
end
|
193
|
+
|
194
|
+
#
|
195
|
+
# Check for a cyclic graph below the given node. Raises
|
196
|
+
# Rake::CompTree::Error::CircularError if found.
|
197
|
+
#
|
198
|
+
# Arguments:
|
199
|
+
#
|
200
|
+
# +name+ -- (Symbol) node name.
|
201
|
+
#
|
202
|
+
def check_circular(name)
|
203
|
+
helper = lambda { |root, chain|
|
204
|
+
if chain.include? root
|
205
|
+
raise Error::CircularError,
|
206
|
+
"Circular dependency detected: #{root} => #{chain.last} => #{root}"
|
207
|
+
end
|
208
|
+
@nodes[root].children.each { |child|
|
209
|
+
helper.call(child.name, chain + [root])
|
210
|
+
}
|
211
|
+
}
|
212
|
+
helper.call(name, [])
|
213
|
+
end
|
214
|
+
|
215
|
+
#
|
216
|
+
# Compute this node.
|
217
|
+
#
|
218
|
+
# Arguments:
|
219
|
+
#
|
220
|
+
# +name+ -- (Symbol) node name.
|
221
|
+
#
|
222
|
+
# Options hash:
|
223
|
+
#
|
224
|
+
# <tt>:threads</tt> -- (Integer) Number of parallel threads.
|
225
|
+
#
|
226
|
+
# <tt>:fork</tt> -- (boolean) Whether to fork each computation
|
227
|
+
# node into its own process.
|
228
|
+
#
|
229
|
+
# Defaults options are taken from Driver::DEFAULTS.
|
230
|
+
#
|
231
|
+
def compute(name, opts = nil)
|
232
|
+
#
|
233
|
+
# Undocumented options:
|
234
|
+
#
|
235
|
+
# <tt>:wait_interval</tt> -- (seconds) (Obscure) How long to
|
236
|
+
# wait after an IPC failure.
|
237
|
+
#
|
238
|
+
# <tt>:timeout</tt> -- (seconds) (Obscure) Give up after this
|
239
|
+
# period of persistent IPC failures.
|
240
|
+
#
|
241
|
+
|
242
|
+
abort_on_exception {
|
243
|
+
compute_private(name, opts || Hash.new)
|
244
|
+
}
|
245
|
+
end
|
246
|
+
|
247
|
+
private
|
248
|
+
|
249
|
+
def compute_private(name, opts_in)
|
250
|
+
opts = DEFAULTS.merge(opts_in)
|
251
|
+
root = @nodes[name]
|
252
|
+
|
253
|
+
if opts[:threads] < 1
|
254
|
+
raise Error::ArgumentError, "threads is #{opts[:threads]}"
|
255
|
+
end
|
256
|
+
|
257
|
+
if opts[:threads] == 1
|
258
|
+
root.result = root.compute_now
|
259
|
+
elsif opts[:fork] and not @node_class.discard_result?
|
260
|
+
#
|
261
|
+
# Use buckets to send results across forks.
|
262
|
+
#
|
263
|
+
result = nil
|
264
|
+
BucketIPC::Driver.new(opts[:threads], opts) { |buckets|
|
265
|
+
result =
|
266
|
+
Algorithm.compute_multithreaded(
|
267
|
+
root, opts[:threads], opts[:fork], buckets)
|
268
|
+
}
|
269
|
+
result
|
270
|
+
else
|
271
|
+
#
|
272
|
+
# Multithreaded computation without fork.
|
273
|
+
#
|
274
|
+
Algorithm.compute_multithreaded(
|
275
|
+
root, opts[:threads], opts[:fork], nil)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
|
282
|
+
|
283
|
+
######################################################
|
284
|
+
#
|
285
|
+
# **** DO NOT EDIT ****
|
286
|
+
#
|
287
|
+
# **** THIS IS A GENERATED FILE *****
|
288
|
+
#
|
289
|
+
######################################################
|
290
|
+
|
291
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
|
4
|
+
######################################################
|
5
|
+
#
|
6
|
+
# **** DO NOT EDIT ****
|
7
|
+
#
|
8
|
+
# **** THIS IS A GENERATED FILE *****
|
9
|
+
#
|
10
|
+
######################################################
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
module Rake::CompTree
|
15
|
+
module Error
|
16
|
+
# Base class for Rake::CompTree errors.
|
17
|
+
class Base < StandardError ; end
|
18
|
+
|
19
|
+
# Internal error inside Rake::CompTree. Please send a bug report.
|
20
|
+
class AssertionFailed < Base ; end
|
21
|
+
|
22
|
+
# Bad arguments were passed to a method.
|
23
|
+
class ArgumentError < Base ; end
|
24
|
+
|
25
|
+
#
|
26
|
+
# Attempt to redefine a Node.
|
27
|
+
#
|
28
|
+
# If you wish to only replace the function, set
|
29
|
+
# driver.nodes[name].function = some_new_lambda
|
30
|
+
#
|
31
|
+
class RedefinitionError < Base ; end
|
32
|
+
|
33
|
+
# A Cyclic graph was detected.
|
34
|
+
class CircularError < Base ; end
|
35
|
+
|
36
|
+
# No function was defined for this node.
|
37
|
+
class NoFunctionError < Base ; end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
######################################################
|
44
|
+
#
|
45
|
+
# **** DO NOT EDIT ****
|
46
|
+
#
|
47
|
+
# **** THIS IS A GENERATED FILE *****
|
48
|
+
#
|
49
|
+
######################################################
|
50
|
+
|
51
|
+
|
@@ -0,0 +1,189 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
|
4
|
+
######################################################
|
5
|
+
#
|
6
|
+
# **** DO NOT EDIT ****
|
7
|
+
#
|
8
|
+
# **** THIS IS A GENERATED FILE *****
|
9
|
+
#
|
10
|
+
######################################################
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
require 'rake/comp_tree/quix/diagnostic'
|
15
|
+
require 'thread'
|
16
|
+
|
17
|
+
module Rake::CompTree
|
18
|
+
#
|
19
|
+
# Base class for nodes in the computation tree.
|
20
|
+
#
|
21
|
+
class Node
|
22
|
+
include Quix::Diagnostic #:nodoc:
|
23
|
+
|
24
|
+
attr_reader :name #:nodoc:
|
25
|
+
|
26
|
+
attr_accessor :parents #:nodoc:
|
27
|
+
attr_accessor :children #:nodoc:
|
28
|
+
attr_accessor :function #:nodoc:
|
29
|
+
attr_accessor :result #:nodoc:
|
30
|
+
attr_accessor :shared_lock #:nodoc:
|
31
|
+
|
32
|
+
#
|
33
|
+
# Create a node
|
34
|
+
#
|
35
|
+
def initialize(name) #:nodoc:
|
36
|
+
@name = name
|
37
|
+
@mutex = Mutex.new
|
38
|
+
@children = []
|
39
|
+
@parents = []
|
40
|
+
reset_self
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Reset the computation for this node.
|
45
|
+
#
|
46
|
+
def reset_self #:nodoc:
|
47
|
+
@shared_lock = 0
|
48
|
+
@children_results = nil
|
49
|
+
@result = nil
|
50
|
+
end
|
51
|
+
|
52
|
+
#
|
53
|
+
# Reset the computation for this node and all children.
|
54
|
+
#
|
55
|
+
def reset #:nodoc:
|
56
|
+
each_downward { |node|
|
57
|
+
node.reset_self
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
def each_downward(&block) #:nodoc:
|
62
|
+
block.call(self)
|
63
|
+
@children.each { |child|
|
64
|
+
child.each_downward(&block)
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
def each_upward(&block) #:nodoc:
|
69
|
+
block.call(self)
|
70
|
+
@parents.each { |parent|
|
71
|
+
parent.each_upward(&block)
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def each_child #:nodoc:
|
76
|
+
@children.each { |child|
|
77
|
+
yield(child)
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# Force computation of all children; intended for
|
83
|
+
# single-threaded mode.
|
84
|
+
#
|
85
|
+
def compute_now #:nodoc:
|
86
|
+
unless @children_results
|
87
|
+
@children_results = @children.map { |child|
|
88
|
+
child.compute_now
|
89
|
+
}
|
90
|
+
end
|
91
|
+
compute
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# If all children have been computed, return their results;
|
96
|
+
# otherwise return nil.
|
97
|
+
#
|
98
|
+
def children_results #:nodoc:
|
99
|
+
if @children_results
|
100
|
+
@children_results
|
101
|
+
else
|
102
|
+
results = @children.map { |child|
|
103
|
+
if child_result = child.result
|
104
|
+
child_result
|
105
|
+
else
|
106
|
+
return nil
|
107
|
+
end
|
108
|
+
}
|
109
|
+
@children_results = results
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def trace_compute #:nodoc:
|
114
|
+
debug {
|
115
|
+
# --- own mutex
|
116
|
+
trace "Computing #{@name}"
|
117
|
+
raise Error::AssertionFailed if @result
|
118
|
+
raise Error::AssertionFailed unless @mutex.locked?
|
119
|
+
raise Error::AssertionFailed unless @children_results
|
120
|
+
}
|
121
|
+
end
|
122
|
+
|
123
|
+
#
|
124
|
+
# Compute this node; children must be computed and lock must be
|
125
|
+
# already acquired.
|
126
|
+
#
|
127
|
+
def compute #:nodoc:
|
128
|
+
unless defined?(@function) and @function
|
129
|
+
raise Error::NoFunctionError,
|
130
|
+
"No function was defined for node '#{@name.inspect}'"
|
131
|
+
end
|
132
|
+
@function.call(*@children_results)
|
133
|
+
end
|
134
|
+
|
135
|
+
def try_lock #:nodoc:
|
136
|
+
# --- shared tree mutex and own mutex
|
137
|
+
if @shared_lock == 0 and @mutex.try_lock
|
138
|
+
trace "Locking #{@name}"
|
139
|
+
each_upward { |node|
|
140
|
+
node.shared_lock += 1
|
141
|
+
trace "#{node.name} locked by #{@name}: level: #{node.shared_lock}"
|
142
|
+
}
|
143
|
+
true
|
144
|
+
else
|
145
|
+
false
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def unlock #:nodoc:
|
150
|
+
# --- shared tree mutex and own mutex
|
151
|
+
debug {
|
152
|
+
raise Error::AssertionFailed unless @mutex.locked?
|
153
|
+
trace "Unlocking #{@name}"
|
154
|
+
}
|
155
|
+
each_upward { |node|
|
156
|
+
node.shared_lock -= 1
|
157
|
+
debug {
|
158
|
+
if node.shared_lock == 0
|
159
|
+
trace "#{node.name} unlocked by #{@name}"
|
160
|
+
end
|
161
|
+
}
|
162
|
+
}
|
163
|
+
@mutex.unlock
|
164
|
+
end
|
165
|
+
|
166
|
+
class << self
|
167
|
+
#
|
168
|
+
# Throw away the computation result?
|
169
|
+
#
|
170
|
+
# This Node base class always returns false.
|
171
|
+
#
|
172
|
+
def discard_result?
|
173
|
+
false
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
|
181
|
+
######################################################
|
182
|
+
#
|
183
|
+
# **** DO NOT EDIT ****
|
184
|
+
#
|
185
|
+
# **** THIS IS A GENERATED FILE *****
|
186
|
+
#
|
187
|
+
######################################################
|
188
|
+
|
189
|
+
|