sass 3.1.4 → 3.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/REVISION +1 -0
- data/VERSION +1 -1
- data/test/sass/logger_test.rb +0 -0
- data/vendor/fssm/Gemfile +3 -0
- data/vendor/fssm/LICENSE +1 -1
- data/vendor/fssm/README.markdown +55 -27
- data/vendor/fssm/Rakefile +6 -54
- data/vendor/fssm/example.rb +6 -3
- data/vendor/fssm/fssm.gemspec +17 -70
- data/vendor/fssm/lib/fssm.rb +7 -3
- data/vendor/fssm/lib/fssm/backends/fsevents.rb +1 -1
- data/vendor/fssm/lib/fssm/backends/inotify.rb +2 -2
- data/vendor/fssm/lib/fssm/backends/polling.rb +2 -2
- data/vendor/fssm/lib/fssm/backends/rbfsevent.rb +42 -0
- data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +10 -10
- data/vendor/fssm/lib/fssm/monitor.rb +19 -9
- data/vendor/fssm/lib/fssm/path.rb +24 -21
- data/vendor/fssm/lib/fssm/pathname.rb +13 -479
- data/vendor/fssm/lib/fssm/state/directory.rb +29 -11
- data/vendor/fssm/lib/fssm/state/file.rb +1 -1
- data/vendor/fssm/lib/fssm/support.rb +41 -12
- data/vendor/fssm/lib/fssm/tree.rb +6 -6
- data/vendor/fssm/lib/fssm/version.rb +3 -0
- data/vendor/fssm/profile/prof-cache.rb +3 -3
- data/vendor/fssm/profile/prof-pathname-rubinius.rb +35 -0
- data/vendor/fssm/profile/prof-pathname.rb +7 -7
- data/vendor/fssm/spec/count_down_latch.rb +151 -0
- data/vendor/fssm/spec/monitor_spec.rb +202 -0
- data/vendor/fssm/spec/path_spec.rb +36 -15
- data/vendor/fssm/spec/spec_helper.rb +6 -6
- metadata +218 -299
- data/lib/sass.rbc +0 -865
- data/lib/sass/cache_stores.rbc +0 -210
- data/lib/sass/cache_stores/base.rbc +0 -1110
- data/lib/sass/cache_stores/chain.rbc +0 -759
- data/lib/sass/cache_stores/filesystem.rbc +0 -1170
- data/lib/sass/cache_stores/memory.rbc +0 -892
- data/lib/sass/callbacks.rbc +0 -623
- data/lib/sass/css.rbc +0 -3483
- data/lib/sass/engine.rbc +0 -19260
- data/lib/sass/environment.rbc +0 -1829
- data/lib/sass/error.rbc +0 -2858
- data/lib/sass/importers.rbc +0 -162
- data/lib/sass/importers/base.rbc +0 -677
- data/lib/sass/importers/filesystem.rbc +0 -2910
- data/lib/sass/less.rbc +0 -11309
- data/lib/sass/plugin.rbc +0 -1360
- data/lib/sass/plugin/compiler.rbc +0 -4205
- data/lib/sass/plugin/configuration.rbc +0 -1514
- data/lib/sass/plugin/generic.rbc +0 -206
- data/lib/sass/plugin/staleness_checker.rbc +0 -2545
- data/lib/sass/railtie.rbc +0 -259
- data/lib/sass/root.rbc +0 -160
- data/lib/sass/script.rbc +0 -728
- data/lib/sass/script/bool.rbc +0 -366
- data/lib/sass/script/color.rbc +0 -7884
- data/lib/sass/script/css_lexer.rbc +0 -793
- data/lib/sass/script/css_parser.rbc +0 -620
- data/lib/sass/script/funcall.rbc +0 -4325
- data/lib/sass/script/functions.rbc +0 -15331
- data/lib/sass/script/interpolation.rbc +0 -1181
- data/lib/sass/script/lexer.rbc +0 -7136
- data/lib/sass/script/list.rbc +0 -1795
- data/lib/sass/script/literal.rbc +0 -3411
- data/lib/sass/script/node.rbc +0 -1176
- data/lib/sass/script/number.rbc +0 -5978
- data/lib/sass/script/operation.rbc +0 -1684
- data/lib/sass/script/parser.rbc +0 -9739
- data/lib/sass/script/string.rbc +0 -965
- data/lib/sass/script/string_interpolation.rbc +0 -1619
- data/lib/sass/script/unary_operation.rbc +0 -1120
- data/lib/sass/script/variable.rbc +0 -899
- data/lib/sass/scss.rbc +0 -242
- data/lib/sass/scss/css_parser.rbc +0 -1098
- data/lib/sass/scss/parser.rbc +0 -20522
- data/lib/sass/scss/rx.rbc +0 -2878
- data/lib/sass/scss/sass_parser.rbc +0 -287
- data/lib/sass/scss/script_lexer.rbc +0 -404
- data/lib/sass/scss/script_parser.rbc +0 -482
- data/lib/sass/scss/static_parser.rbc +0 -963
- data/lib/sass/selector.rbc +0 -4125
- data/lib/sass/selector/abstract_sequence.rbc +0 -798
- data/lib/sass/selector/comma_sequence.rbc +0 -1806
- data/lib/sass/selector/sequence.rbc +0 -4727
- data/lib/sass/selector/simple.rbc +0 -1490
- data/lib/sass/selector/simple_sequence.rbc +0 -2298
- data/lib/sass/shared.rbc +0 -1093
- data/lib/sass/tree/charset_node.rbc +0 -381
- data/lib/sass/tree/comment_node.rbc +0 -1175
- data/lib/sass/tree/debug_node.rbc +0 -365
- data/lib/sass/tree/directive_node.rbc +0 -298
- data/lib/sass/tree/each_node.rbc +0 -347
- data/lib/sass/tree/extend_node.rbc +0 -335
- data/lib/sass/tree/for_node.rbc +0 -407
- data/lib/sass/tree/function_node.rbc +0 -395
- data/lib/sass/tree/if_node.rbc +0 -995
- data/lib/sass/tree/import_node.rbc +0 -1327
- data/lib/sass/tree/media_node.rbc +0 -423
- data/lib/sass/tree/mixin_def_node.rbc +0 -395
- data/lib/sass/tree/mixin_node.rbc +0 -377
- data/lib/sass/tree/node.rbc +0 -2394
- data/lib/sass/tree/prop_node.rbc +0 -2695
- data/lib/sass/tree/return_node.rbc +0 -365
- data/lib/sass/tree/root_node.rbc +0 -558
- data/lib/sass/tree/rule_node.rbc +0 -1597
- data/lib/sass/tree/variable_node.rbc +0 -425
- data/lib/sass/tree/visitors/base.rbc +0 -981
- data/lib/sass/tree/visitors/check_nesting.rbc +0 -3247
- data/lib/sass/tree/visitors/convert.rbc +0 -6529
- data/lib/sass/tree/visitors/cssize.rbc +0 -4133
- data/lib/sass/tree/visitors/perform.rbc +0 -8169
- data/lib/sass/tree/visitors/to_css.rbc +0 -6971
- data/lib/sass/tree/warn_node.rbc +0 -365
- data/lib/sass/tree/while_node.rbc +0 -317
- data/lib/sass/util.rbc +0 -9956
- data/lib/sass/util/subset_map.rbc +0 -1304
- data/lib/sass/version.rbc +0 -1763
- data/test/sass/cache_test.rbc +0 -2159
- data/test/sass/callbacks_test.rbc +0 -1518
- data/test/sass/conversion_test.rbc +0 -7840
- data/test/sass/css2sass_test.rbc +0 -3805
- data/test/sass/engine_test.rbc +0 -30858
- data/test/sass/extend_test.rbc +0 -8794
- data/test/sass/functions_test.rbc +0 -21318
- data/test/sass/importer_test.rbc +0 -4520
- data/test/sass/less_conversion_test.rbc +0 -5328
- data/test/sass/mock_importer.rbc +0 -1203
- data/test/sass/plugin_test.rbc +0 -11014
- data/test/sass/script_conversion_test.rbc +0 -4953
- data/test/sass/script_test.rbc +0 -13038
- data/test/sass/scss/css_test.rbc +0 -9621
- data/test/sass/scss/rx_test.rbc +0 -3183
- data/test/sass/scss/scss_test.rbc +0 -10997
- data/test/sass/scss/test_helper.rbc +0 -1103
- data/test/sass/test_helper.rbc +0 -306
- data/test/sass/util/subset_map_test.rbc +0 -2755
- data/test/sass/util_test.rbc +0 -6899
- data/test/test_helper.rbc +0 -2020
- data/vendor/fssm/VERSION.yml +0 -5
- data/vendor/fssm/pkg/fssm-0.0.8.gem +0 -0
@@ -2,13 +2,15 @@ module FSSM::State
|
|
2
2
|
class Directory
|
3
3
|
attr_reader :path
|
4
4
|
|
5
|
-
def initialize(path)
|
6
|
-
@path
|
7
|
-
@
|
5
|
+
def initialize(path, options={})
|
6
|
+
@path = path
|
7
|
+
@options = options
|
8
|
+
@cache = FSSM::Tree::Cache.new
|
8
9
|
end
|
9
10
|
|
10
11
|
def refresh(base=nil, skip_callbacks=false)
|
11
|
-
|
12
|
+
base_path = FSSM::Pathname.for(base || @path.to_pathname).expand_path
|
13
|
+
previous, current = recache(base_path)
|
12
14
|
|
13
15
|
unless skip_callbacks
|
14
16
|
deleted(previous, current)
|
@@ -20,31 +22,36 @@ module FSSM::State
|
|
20
22
|
private
|
21
23
|
|
22
24
|
def created(previous, current)
|
23
|
-
(current.keys - previous.keys).each
|
25
|
+
(current.keys - previous.keys).sort.each do |file|
|
26
|
+
@path.create(file, current[file][1])
|
27
|
+
end
|
24
28
|
end
|
25
29
|
|
26
30
|
def deleted(previous, current)
|
27
|
-
(previous.keys - current.keys).each
|
31
|
+
(previous.keys - current.keys).sort.reverse.each do |file|
|
32
|
+
@path.delete(file, previous[file][1])
|
33
|
+
end
|
28
34
|
end
|
29
35
|
|
30
36
|
def modified(previous, current)
|
31
37
|
(current.keys & previous.keys).each do |file|
|
32
|
-
|
38
|
+
current_data = current[file]
|
39
|
+
@path.update(file, current_data[1]) if (current_data[0] <=> previous[file][0]) != 0
|
33
40
|
end
|
34
41
|
end
|
35
42
|
|
36
43
|
def recache(base)
|
37
|
-
base
|
38
|
-
previous =
|
44
|
+
base = FSSM::Pathname.for(base)
|
45
|
+
previous = cache_entries
|
39
46
|
snapshot(base)
|
40
|
-
current =
|
47
|
+
current = cache_entries
|
41
48
|
[previous, current]
|
42
49
|
end
|
43
50
|
|
44
51
|
def snapshot(base)
|
45
52
|
base = FSSM::Pathname.for(base)
|
46
53
|
@cache.unset(base)
|
47
|
-
@path.glob.each {|glob| add_glob(base, glob)}
|
54
|
+
@path.glob.each { |glob| add_glob(base, glob) }
|
48
55
|
end
|
49
56
|
|
50
57
|
def add_glob(base, glob)
|
@@ -53,5 +60,16 @@ module FSSM::State
|
|
53
60
|
end
|
54
61
|
end
|
55
62
|
|
63
|
+
def cache_entries
|
64
|
+
entries = tag_entries(@cache.files, :file)
|
65
|
+
entries.merge! tag_entries(@cache.directories, :directory) if @options[:directories]
|
66
|
+
entries
|
67
|
+
end
|
68
|
+
|
69
|
+
def tag_entries(entries, tag)
|
70
|
+
tagged_entries = {}
|
71
|
+
entries.each_pair { |fname, mtime| tagged_entries[fname] = [mtime, tag] }
|
72
|
+
tagged_entries
|
73
|
+
end
|
56
74
|
end
|
57
75
|
end
|
@@ -8,7 +8,7 @@ module FSSM::State
|
|
8
8
|
|
9
9
|
def refresh(base=nil, skip_callbacks=false)
|
10
10
|
base ||= @path.to_pathname
|
11
|
-
used_to_exist, @exists = @exists, base.
|
11
|
+
used_to_exist, @exists = @exists, base.exist?
|
12
12
|
# this handles bad symlinks without failing. why handle bad symlinks at
|
13
13
|
# all? well, we could still be interested in their creation and deletion.
|
14
14
|
old_mtime, @mtime = @mtime, base.symlink? ? Time.at(0) : base.mtime if @exists
|
@@ -2,15 +2,34 @@ require 'rbconfig'
|
|
2
2
|
|
3
3
|
module FSSM::Support
|
4
4
|
class << self
|
5
|
-
def
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
5
|
+
def usable_backend
|
6
|
+
choice = case
|
7
|
+
when mac? && !lion? && !jruby? && carbon_core?
|
8
|
+
'FSEvents'
|
9
|
+
when mac? && rb_fsevent?
|
10
|
+
'RBFSEvent'
|
11
|
+
when linux? && rb_inotify?
|
12
|
+
'Inotify'
|
13
|
+
else
|
14
|
+
'Polling'
|
15
|
+
end
|
16
|
+
|
17
|
+
if (mac? || linux?) && choice == 'Polling'
|
18
|
+
optimal = case
|
19
|
+
when mac?
|
20
|
+
'rb-fsevent'
|
21
|
+
when linux?
|
22
|
+
'rb-inotify'
|
23
|
+
end
|
24
|
+
FSSM.dbg("An optimized backend is available for this platform!")
|
25
|
+
FSSM.dbg(" gem install #{optimal}")
|
13
26
|
end
|
27
|
+
|
28
|
+
choice
|
29
|
+
end
|
30
|
+
|
31
|
+
def backend
|
32
|
+
@@backend ||= usable_backend
|
14
33
|
end
|
15
34
|
|
16
35
|
def jruby?
|
@@ -21,6 +40,10 @@ module FSSM::Support
|
|
21
40
|
Config::CONFIG['target_os'] =~ /darwin/i
|
22
41
|
end
|
23
42
|
|
43
|
+
def lion?
|
44
|
+
Config::CONFIG['target_os'] =~ /darwin11/i
|
45
|
+
end
|
46
|
+
|
24
47
|
def linux?
|
25
48
|
Config::CONFIG['target_os'] =~ /linux/i
|
26
49
|
end
|
@@ -31,13 +54,21 @@ module FSSM::Support
|
|
31
54
|
OSX.require_framework '/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework'
|
32
55
|
true
|
33
56
|
rescue LoadError
|
34
|
-
|
57
|
+
false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def rb_fsevent?
|
62
|
+
begin
|
63
|
+
require 'rb-fsevent'
|
64
|
+
defined?(FSEvent::VERSION) ? FSEvent::VERSION.to_f >= 0.4 : false
|
65
|
+
rescue LoadError
|
35
66
|
false
|
36
67
|
end
|
37
68
|
end
|
38
69
|
|
39
70
|
def rb_inotify?
|
40
|
-
|
71
|
+
begin
|
41
72
|
require 'rb-inotify'
|
42
73
|
if defined?(INotify::VERSION)
|
43
74
|
version = INotify::VERSION
|
@@ -46,8 +77,6 @@ module FSSM::Support
|
|
46
77
|
rescue LoadError
|
47
78
|
false
|
48
79
|
end
|
49
|
-
STDERR.puts("Warning: Unable to load rb-inotify >= 0.5.1. Inotify will be unavailable.") unless found
|
50
|
-
found
|
51
80
|
end
|
52
81
|
|
53
82
|
def use_block(context, block)
|
@@ -34,8 +34,8 @@ module FSSM::Tree
|
|
34
34
|
def each(prefix=nil, &block)
|
35
35
|
@children.each do |segment, node|
|
36
36
|
cprefix = prefix ?
|
37
|
-
|
38
|
-
|
37
|
+
FSSM::Pathname.for(prefix).join(segment) :
|
38
|
+
FSSM::Pathname.for(segment)
|
39
39
|
block.call([cprefix, node])
|
40
40
|
node.each(cprefix, &block)
|
41
41
|
end
|
@@ -54,7 +54,7 @@ module FSSM::Tree
|
|
54
54
|
end
|
55
55
|
|
56
56
|
segment = key.pop
|
57
|
-
node
|
57
|
+
node = descendant(key)
|
58
58
|
|
59
59
|
return unless node
|
60
60
|
|
@@ -84,12 +84,12 @@ module FSSM::Tree
|
|
84
84
|
end
|
85
85
|
|
86
86
|
def recurse(key, create=false)
|
87
|
-
key
|
87
|
+
key = key_segments(key)
|
88
88
|
node = self
|
89
89
|
|
90
90
|
until key.empty?
|
91
91
|
segment = key.shift
|
92
|
-
node
|
92
|
+
node = create ? node.child!(segment) : node.child(segment)
|
93
93
|
return nil unless node
|
94
94
|
end
|
95
95
|
|
@@ -127,7 +127,7 @@ module FSSM::Tree
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def from_path(path)
|
130
|
-
path
|
130
|
+
path = FSSM::Pathname.for(path)
|
131
131
|
@ftype = path.ftype
|
132
132
|
# this handles bad symlinks without failing. why handle bad symlinks at
|
133
133
|
# all? well, we could still be interested in their creation and deletion.
|
@@ -5,7 +5,7 @@ require 'fssm'
|
|
5
5
|
require 'rubygems'
|
6
6
|
require 'ruby-prof'
|
7
7
|
|
8
|
-
$test_path
|
8
|
+
$test_path = FSSM::Pathname.new('..').expand_path
|
9
9
|
$test_files = FSSM::Pathname.glob(File.join($test_path, '**', '*'))
|
10
10
|
|
11
11
|
RubyProf.start
|
@@ -33,8 +33,8 @@ cache = FSSM::Tree::Cache.new
|
|
33
33
|
print "\n\n"
|
34
34
|
end
|
35
35
|
|
36
|
-
result
|
37
|
-
output
|
36
|
+
result = RubyProf.stop
|
37
|
+
output = File.new('prof.html', 'w+')
|
38
38
|
|
39
39
|
printer = RubyProf::GraphHtmlPrinter.new(result)
|
40
40
|
printer.print(output, :min_percent => 1)
|
@@ -0,0 +1,35 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
$test_path = "#{Pathname.new('..').expand_path}"
|
6
|
+
$iterations = 900000
|
7
|
+
|
8
|
+
if ARGV.first == 'native'
|
9
|
+
puts "Using native Pathname"
|
10
|
+
|
11
|
+
class Pathname
|
12
|
+
# original segments implementation I was using with
|
13
|
+
# the plain ruby Pathname library.
|
14
|
+
def segments
|
15
|
+
prefix, names = split_names(@path)
|
16
|
+
names.unshift(prefix) unless prefix.empty?
|
17
|
+
names.shift if names[0] == '.'
|
18
|
+
names
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
$iterations.times do |num|
|
23
|
+
p = ::Pathname.new($test_path)
|
24
|
+
segments = p.segments
|
25
|
+
end
|
26
|
+
else
|
27
|
+
puts "Using FSSM::Pathname"
|
28
|
+
|
29
|
+
require 'fssm'
|
30
|
+
|
31
|
+
$iterations.times do |num|
|
32
|
+
p = FSSM::Pathname.new($test_path)
|
33
|
+
segments = p.segments
|
34
|
+
end
|
35
|
+
end
|
@@ -6,7 +6,7 @@ require 'pathname'
|
|
6
6
|
require 'rubygems'
|
7
7
|
require 'ruby-prof'
|
8
8
|
|
9
|
-
$test_path
|
9
|
+
$test_path = "#{Pathname.new('..').expand_path}"
|
10
10
|
$iterations = 90000
|
11
11
|
|
12
12
|
class Pathname
|
@@ -32,15 +32,15 @@ $iterations.times do |num|
|
|
32
32
|
puts "FSSM::Pathname iteration #{iteration}"
|
33
33
|
|
34
34
|
RubyProf.resume
|
35
|
-
p
|
35
|
+
p = FSSM::Pathname.new($test_path)
|
36
36
|
segments = p.segments
|
37
37
|
RubyProf.pause
|
38
38
|
end
|
39
39
|
|
40
40
|
puts "\nFSSM Pathname profile finished\n\n"
|
41
41
|
|
42
|
-
result
|
43
|
-
output
|
42
|
+
result = RubyProf.stop
|
43
|
+
output = File.new('prof-fssm-pathname.html', 'w+')
|
44
44
|
|
45
45
|
printer = RubyProf::GraphHtmlPrinter.new(result)
|
46
46
|
printer.print(output, :min_percent => 1)
|
@@ -54,15 +54,15 @@ $iterations.times do |num|
|
|
54
54
|
puts "::Pathname iteration #{iteration}"
|
55
55
|
|
56
56
|
RubyProf.resume
|
57
|
-
p
|
57
|
+
p = ::Pathname.new($test_path)
|
58
58
|
segments = p.segments
|
59
59
|
RubyProf.pause
|
60
60
|
end
|
61
61
|
|
62
62
|
puts "\nruby Pathname profile finished\n\n"
|
63
63
|
|
64
|
-
result
|
65
|
-
output
|
64
|
+
result = RubyProf.stop
|
65
|
+
output = File.new('prof-plain-pathname.html', 'w+')
|
66
66
|
|
67
67
|
printer = RubyProf::GraphHtmlPrinter.new(result)
|
68
68
|
printer.print(output, :min_percent => 1)
|
@@ -0,0 +1,151 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
require 'thread'
|
5
|
+
|
6
|
+
class CountDownLatch
|
7
|
+
attr_reader :count
|
8
|
+
|
9
|
+
def initialize(to)
|
10
|
+
@count = to.to_i
|
11
|
+
raise ArgumentError, "cannot count down from negative integer" unless @count >= 0
|
12
|
+
@lock = Mutex.new
|
13
|
+
@condition = ConditionVariable.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def count_down
|
17
|
+
@lock.synchronize do
|
18
|
+
@count -= 1 if @count > 0
|
19
|
+
@condition.broadcast if @count == 0
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def wait
|
24
|
+
@lock.synchronize do
|
25
|
+
@condition.wait(@lock) while @count > 0
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
if $0 == __FILE__
|
31
|
+
require 'test/unit'
|
32
|
+
|
33
|
+
class CountDownLatchTest < Test::Unit::TestCase
|
34
|
+
def test_requires_positive_count
|
35
|
+
assert_raise(ArgumentError) { CountDownLatch.new(-1) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_basic_latch_usage
|
39
|
+
latch = CountDownLatch.new(1)
|
40
|
+
name = "foo"
|
41
|
+
Thread.new do
|
42
|
+
name = "bar"
|
43
|
+
latch.count_down
|
44
|
+
end
|
45
|
+
latch.wait
|
46
|
+
assert_equal(0, latch.count)
|
47
|
+
assert_equal("bar", name)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_basic_latch_usage_inverted
|
51
|
+
latch = CountDownLatch.new(1)
|
52
|
+
name = "foo"
|
53
|
+
Thread.new do
|
54
|
+
latch.wait
|
55
|
+
assert_equal(0, latch.count)
|
56
|
+
assert_equal("bar", name)
|
57
|
+
end
|
58
|
+
name = "bar"
|
59
|
+
latch.count_down
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_count_down_from_zero_skips_wait
|
63
|
+
latch = CountDownLatch.new(0)
|
64
|
+
latch.wait
|
65
|
+
assert_equal(0, latch.count)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_count_down_twice_with_thread
|
69
|
+
latch = CountDownLatch.new(2)
|
70
|
+
name = "foo"
|
71
|
+
Thread.new do
|
72
|
+
latch.count_down
|
73
|
+
name = "bar"
|
74
|
+
latch.count_down
|
75
|
+
end
|
76
|
+
latch.wait
|
77
|
+
assert_equal(0, latch.count)
|
78
|
+
assert_equal("bar", name)
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_count_down_twice_with_two_parallel_threads
|
82
|
+
latch = CountDownLatch.new(2)
|
83
|
+
name = "foo"
|
84
|
+
Thread.new { latch.count_down }
|
85
|
+
Thread.new do
|
86
|
+
name = "bar"
|
87
|
+
latch.count_down
|
88
|
+
end
|
89
|
+
latch.wait
|
90
|
+
assert_equal(0, latch.count)
|
91
|
+
assert_equal("bar", name)
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_count_down_twice_with_two_chained_threads
|
95
|
+
latch = CountDownLatch.new(2)
|
96
|
+
name = "foo"
|
97
|
+
Thread.new do
|
98
|
+
latch.count_down
|
99
|
+
Thread.new do
|
100
|
+
name = "bar"
|
101
|
+
latch.count_down
|
102
|
+
end
|
103
|
+
end
|
104
|
+
latch.wait
|
105
|
+
assert_equal(0, latch.count)
|
106
|
+
assert_equal("bar", name)
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_count_down_with_multiple_waiters
|
110
|
+
proceed_latch = CountDownLatch.new(2)
|
111
|
+
check_latch = CountDownLatch.new(2)
|
112
|
+
results = {}
|
113
|
+
Thread.new do
|
114
|
+
proceed_latch.wait
|
115
|
+
results[:first] = 1
|
116
|
+
check_latch.count_down
|
117
|
+
end
|
118
|
+
Thread.new do
|
119
|
+
proceed_latch.wait
|
120
|
+
results[:second] = 2
|
121
|
+
check_latch.count_down
|
122
|
+
end
|
123
|
+
assert_equal({}, results)
|
124
|
+
proceed_latch.count_down
|
125
|
+
proceed_latch.count_down
|
126
|
+
check_latch.wait
|
127
|
+
assert_equal(0, proceed_latch.count)
|
128
|
+
assert_equal(0, check_latch.count)
|
129
|
+
assert_equal({:first => 1, :second => 2}, results)
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_interleaved_latches
|
133
|
+
change_1_latch = CountDownLatch.new(1)
|
134
|
+
check_latch = CountDownLatch.new(1)
|
135
|
+
change_2_latch = CountDownLatch.new(1)
|
136
|
+
name = "foo"
|
137
|
+
Thread.new do
|
138
|
+
name = "bar"
|
139
|
+
change_1_latch.count_down
|
140
|
+
check_latch.wait
|
141
|
+
name = "man"
|
142
|
+
change_2_latch.count_down
|
143
|
+
end
|
144
|
+
change_1_latch.wait
|
145
|
+
assert_equal("bar", name)
|
146
|
+
check_latch.count_down
|
147
|
+
change_2_latch.wait
|
148
|
+
assert_equal("man", name)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|