concurrent-ruby 0.1.1.pre.3 → 0.1.1.pre.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -21
- data/README.md +275 -279
- data/lib/concurrent.rb +27 -28
- data/lib/concurrent/agent.rb +114 -108
- data/lib/concurrent/cached_thread_pool.rb +129 -130
- data/lib/concurrent/defer.rb +65 -67
- data/lib/concurrent/event.rb +60 -60
- data/lib/concurrent/event_machine_defer_proxy.rb +23 -23
- data/lib/concurrent/executor.rb +93 -95
- data/lib/concurrent/fixed_thread_pool.rb +95 -89
- data/lib/concurrent/functions.rb +120 -120
- data/lib/concurrent/future.rb +42 -47
- data/lib/concurrent/global_thread_pool.rb +16 -16
- data/lib/concurrent/goroutine.rb +29 -29
- data/lib/concurrent/null_thread_pool.rb +22 -22
- data/lib/concurrent/obligation.rb +67 -67
- data/lib/concurrent/promise.rb +174 -166
- data/lib/concurrent/reactor.rb +161 -162
- data/lib/concurrent/reactor/drb_async_demux.rb +74 -74
- data/lib/concurrent/reactor/tcp_sync_demux.rb +98 -98
- data/lib/concurrent/thread_pool.rb +76 -69
- data/lib/concurrent/utilities.rb +32 -34
- data/lib/concurrent/version.rb +3 -3
- data/lib/concurrent_ruby.rb +1 -1
- data/md/agent.md +123 -123
- data/md/defer.md +174 -174
- data/md/event.md +32 -32
- data/md/executor.md +176 -176
- data/md/future.md +83 -83
- data/md/goroutine.md +52 -52
- data/md/obligation.md +32 -32
- data/md/promise.md +227 -227
- data/md/thread_pool.md +224 -224
- data/spec/concurrent/agent_spec.rb +386 -380
- data/spec/concurrent/cached_thread_pool_spec.rb +125 -125
- data/spec/concurrent/defer_spec.rb +195 -195
- data/spec/concurrent/event_machine_defer_proxy_spec.rb +256 -253
- data/spec/concurrent/event_spec.rb +134 -134
- data/spec/concurrent/executor_spec.rb +184 -184
- data/spec/concurrent/fixed_thread_pool_spec.rb +83 -84
- data/spec/concurrent/functions_spec.rb +217 -217
- data/spec/concurrent/future_spec.rb +108 -108
- data/spec/concurrent/global_thread_pool_spec.rb +38 -38
- data/spec/concurrent/goroutine_spec.rb +67 -67
- data/spec/concurrent/null_thread_pool_spec.rb +54 -54
- data/spec/concurrent/obligation_shared.rb +135 -121
- data/spec/concurrent/promise_spec.rb +312 -305
- data/spec/concurrent/reactor/drb_async_demux_spec.rb +12 -12
- data/spec/concurrent/reactor/tcp_sync_demux_spec.rb +12 -12
- data/spec/concurrent/reactor_spec.rb +351 -10
- data/spec/concurrent/thread_pool_shared.rb +209 -210
- data/spec/concurrent/utilities_spec.rb +74 -74
- data/spec/spec_helper.rb +44 -30
- metadata +11 -22
- data/lib/concurrent/smart_mutex.rb +0 -66
- data/spec/concurrent/smart_mutex_spec.rb +0 -234
@@ -1,74 +1,74 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'thread'
|
3
|
-
|
4
|
-
describe 'utilities' do
|
5
|
-
|
6
|
-
context '#atomic' do
|
7
|
-
|
8
|
-
it 'calls the block' do
|
9
|
-
@expected = false
|
10
|
-
atomic{ @expected = true }
|
11
|
-
@expected.should be_true
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'passes all arguments to the block' do
|
15
|
-
@expected = nil
|
16
|
-
atomic(1, 2, 3, 4) do |a, b, c, d|
|
17
|
-
@expected = [a, b, c, d]
|
18
|
-
end
|
19
|
-
@expected.should eq [1, 2, 3, 4]
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'returns the result of the block' do
|
23
|
-
expected = atomic{ 'foo' }
|
24
|
-
expected.should eq 'foo'
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'raises an exception if no block is given' do
|
28
|
-
lambda {
|
29
|
-
atomic()
|
30
|
-
}.should raise_error(ArgumentError)
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'creates a new Fiber' do
|
34
|
-
fiber = Fiber.new{ 'foo' }
|
35
|
-
Fiber.should_receive(:new).with(no_args()).and_return(fiber)
|
36
|
-
atomic{ 'foo' }
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'immediately runs the Fiber' do
|
40
|
-
fiber = Fiber.new{ 'foo' }
|
41
|
-
Fiber.stub(:new).with(no_args()).and_return(fiber)
|
42
|
-
fiber.should_receive(:resume).with(no_args())
|
43
|
-
atomic{ 'foo' }
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
context Mutex do
|
48
|
-
|
49
|
-
context '#sync_with_timeout' do
|
50
|
-
|
51
|
-
it 'returns the result of the block if a lock is obtained before timeout' do
|
52
|
-
mutex = Mutex.new
|
53
|
-
result = mutex.sync_with_timeout(30){ 42 }
|
54
|
-
result.should eq 42
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'raises Timeout::Error if the timeout is exceeded' do
|
58
|
-
mutex = Mutex.new
|
59
|
-
thread = Thread.new{ mutex.synchronize{ sleep(30) } }
|
60
|
-
sleep(0.1)
|
61
|
-
lambda {
|
62
|
-
mutex.sync_and_wait(1)
|
63
|
-
}.should raise_error(NoMethodError)
|
64
|
-
Thread.kill(thread)
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'raises an exception if no block given' do
|
68
|
-
lambda {
|
69
|
-
Mutex.new.sync_with_timeout()
|
70
|
-
}.should raise_error(ArgumentError)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'thread'
|
3
|
+
|
4
|
+
describe 'utilities' do
|
5
|
+
|
6
|
+
context '#atomic' do
|
7
|
+
|
8
|
+
it 'calls the block' do
|
9
|
+
@expected = false
|
10
|
+
atomic{ @expected = true }
|
11
|
+
@expected.should be_true
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'passes all arguments to the block' do
|
15
|
+
@expected = nil
|
16
|
+
atomic(1, 2, 3, 4) do |a, b, c, d|
|
17
|
+
@expected = [a, b, c, d]
|
18
|
+
end
|
19
|
+
@expected.should eq [1, 2, 3, 4]
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns the result of the block' do
|
23
|
+
expected = atomic{ 'foo' }
|
24
|
+
expected.should eq 'foo'
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'raises an exception if no block is given' do
|
28
|
+
lambda {
|
29
|
+
atomic()
|
30
|
+
}.should raise_error(ArgumentError)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'creates a new Fiber' do
|
34
|
+
fiber = Fiber.new{ 'foo' }
|
35
|
+
Fiber.should_receive(:new).with(no_args()).and_return(fiber)
|
36
|
+
atomic{ 'foo' }
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'immediately runs the Fiber' do
|
40
|
+
fiber = Fiber.new{ 'foo' }
|
41
|
+
Fiber.stub(:new).with(no_args()).and_return(fiber)
|
42
|
+
fiber.should_receive(:resume).with(no_args())
|
43
|
+
atomic{ 'foo' }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context Mutex do
|
48
|
+
|
49
|
+
context '#sync_with_timeout' do
|
50
|
+
|
51
|
+
it 'returns the result of the block if a lock is obtained before timeout' do
|
52
|
+
mutex = Mutex.new
|
53
|
+
result = mutex.sync_with_timeout(30){ 42 }
|
54
|
+
result.should eq 42
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'raises Timeout::Error if the timeout is exceeded' do
|
58
|
+
mutex = Mutex.new
|
59
|
+
thread = Thread.new{ mutex.synchronize{ sleep(30) } }
|
60
|
+
sleep(0.1)
|
61
|
+
lambda {
|
62
|
+
mutex.sync_and_wait(1)
|
63
|
+
}.should raise_error(NoMethodError)
|
64
|
+
Thread.kill(thread)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'raises an exception if no block given' do
|
68
|
+
lambda {
|
69
|
+
Mutex.new.sync_with_timeout()
|
70
|
+
}.should raise_error(ArgumentError)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,30 +1,44 @@
|
|
1
|
-
require 'simplecov'
|
2
|
-
SimpleCov.start do
|
3
|
-
project_name 'concurrent-ruby'
|
4
|
-
add_filter '/md/'
|
5
|
-
add_filter '/pkg/'
|
6
|
-
add_filter '/spec/'
|
7
|
-
add_filter '/tasks/'
|
8
|
-
end
|
9
|
-
|
10
|
-
require 'eventmachine'
|
11
|
-
|
12
|
-
require 'concurrent'
|
13
|
-
require 'concurrent/functions'
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start do
|
3
|
+
project_name 'concurrent-ruby'
|
4
|
+
add_filter '/md/'
|
5
|
+
add_filter '/pkg/'
|
6
|
+
add_filter '/spec/'
|
7
|
+
add_filter '/tasks/'
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'eventmachine'
|
11
|
+
|
12
|
+
require 'concurrent'
|
13
|
+
require 'concurrent/functions'
|
14
|
+
|
15
|
+
require 'rbconfig'
|
16
|
+
|
17
|
+
def mri?
|
18
|
+
RbConfig::CONFIG['ruby_install_name'] =~ /^ruby$/i
|
19
|
+
end
|
20
|
+
|
21
|
+
def jruby?
|
22
|
+
RbConfig::CONFIG['ruby_install_name'] =~ /^jruby$/i
|
23
|
+
end
|
24
|
+
|
25
|
+
def rbx?
|
26
|
+
RbConfig::CONFIG['ruby_install_name'] =~ /^rbx$/i
|
27
|
+
end
|
28
|
+
|
29
|
+
# import all the support files
|
30
|
+
Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each { |f| require File.expand_path(f) }
|
31
|
+
|
32
|
+
RSpec.configure do |config|
|
33
|
+
config.order = 'random'
|
34
|
+
|
35
|
+
config.before(:suite) do
|
36
|
+
end
|
37
|
+
|
38
|
+
config.before(:each) do
|
39
|
+
end
|
40
|
+
|
41
|
+
config.after(:each) do
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
metadata
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: concurrent-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.1.pre.
|
5
|
-
prerelease: 6
|
4
|
+
version: 0.1.1.pre.4
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Jerry D'Antonio
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-08-
|
11
|
+
date: 2013-08-13 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: functional-ruby
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - ~>
|
20
18
|
- !ruby/object:Gem::Version
|
@@ -22,7 +20,6 @@ dependencies:
|
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - ~>
|
28
25
|
- !ruby/object:Gem::Version
|
@@ -30,23 +27,19 @@ dependencies:
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: bundler
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
|
-
description:
|
47
|
-
|
48
|
-
|
49
|
-
'
|
41
|
+
description: |2
|
42
|
+
A gem for adding Erlang, Clojure, and Go inspired concurrent programming tools to Ruby.
|
50
43
|
email: jerry.dantonio@gmail.com
|
51
44
|
executables: []
|
52
45
|
extensions: []
|
@@ -73,7 +66,6 @@ files:
|
|
73
66
|
- lib/concurrent/reactor/drb_async_demux.rb
|
74
67
|
- lib/concurrent/reactor/tcp_sync_demux.rb
|
75
68
|
- lib/concurrent/reactor.rb
|
76
|
-
- lib/concurrent/smart_mutex.rb
|
77
69
|
- lib/concurrent/thread_pool.rb
|
78
70
|
- lib/concurrent/utilities.rb
|
79
71
|
- lib/concurrent/version.rb
|
@@ -105,34 +97,32 @@ files:
|
|
105
97
|
- spec/concurrent/reactor/drb_async_demux_spec.rb
|
106
98
|
- spec/concurrent/reactor/tcp_sync_demux_spec.rb
|
107
99
|
- spec/concurrent/reactor_spec.rb
|
108
|
-
- spec/concurrent/smart_mutex_spec.rb
|
109
100
|
- spec/concurrent/thread_pool_shared.rb
|
110
101
|
- spec/concurrent/utilities_spec.rb
|
111
102
|
- spec/spec_helper.rb
|
112
103
|
homepage: https://github.com/jdantonio/concurrent-ruby/
|
113
104
|
licenses:
|
114
105
|
- MIT
|
106
|
+
metadata: {}
|
115
107
|
post_install_message:
|
116
108
|
rdoc_options: []
|
117
109
|
require_paths:
|
118
110
|
- lib
|
119
111
|
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
-
none: false
|
121
112
|
requirements:
|
122
|
-
- -
|
113
|
+
- - '>='
|
123
114
|
- !ruby/object:Gem::Version
|
124
115
|
version: 1.9.2
|
125
116
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
|
-
none: false
|
127
117
|
requirements:
|
128
|
-
- -
|
118
|
+
- - '>'
|
129
119
|
- !ruby/object:Gem::Version
|
130
120
|
version: 1.3.1
|
131
121
|
requirements: []
|
132
122
|
rubyforge_project:
|
133
|
-
rubygems_version:
|
123
|
+
rubygems_version: 2.0.6
|
134
124
|
signing_key:
|
135
|
-
specification_version:
|
125
|
+
specification_version: 4
|
136
126
|
summary: Erlang, Clojure, and Go inspired concurrent programming tools for Ruby.
|
137
127
|
test_files:
|
138
128
|
- spec/concurrent/agent_spec.rb
|
@@ -152,7 +142,6 @@ test_files:
|
|
152
142
|
- spec/concurrent/reactor/drb_async_demux_spec.rb
|
153
143
|
- spec/concurrent/reactor/tcp_sync_demux_spec.rb
|
154
144
|
- spec/concurrent/reactor_spec.rb
|
155
|
-
- spec/concurrent/smart_mutex_spec.rb
|
156
145
|
- spec/concurrent/thread_pool_shared.rb
|
157
146
|
- spec/concurrent/utilities_spec.rb
|
158
147
|
- spec/spec_helper.rb
|
@@ -1,66 +0,0 @@
|
|
1
|
-
require 'thread'
|
2
|
-
require 'concurrent/utilities'
|
3
|
-
|
4
|
-
module Concurrent
|
5
|
-
|
6
|
-
class SmartMutex
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
@mutex = Mutex.new
|
10
|
-
end
|
11
|
-
|
12
|
-
def alone?
|
13
|
-
Thread.list.length <= 1
|
14
|
-
end
|
15
|
-
|
16
|
-
def lock
|
17
|
-
atomic do
|
18
|
-
@mutex.lock unless alone?
|
19
|
-
self
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def locked?
|
24
|
-
atomic do
|
25
|
-
if alone?
|
26
|
-
false
|
27
|
-
else
|
28
|
-
@mutex.locked?
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def sleep(timeout)
|
34
|
-
if alone?
|
35
|
-
Kernel.sleep(timeout)
|
36
|
-
else
|
37
|
-
@mutex.sleep(timeout)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def synchronize(&block)
|
42
|
-
if alone?
|
43
|
-
yield
|
44
|
-
else
|
45
|
-
@mutex.synchronize(&block)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def try_lock
|
50
|
-
atomic do
|
51
|
-
if alone?
|
52
|
-
true
|
53
|
-
else
|
54
|
-
@mutex.try_lock
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def unlock
|
60
|
-
atomic do
|
61
|
-
@mutex.unlock unless alone?
|
62
|
-
self
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,234 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Concurrent
|
4
|
-
|
5
|
-
describe SmartMutex do
|
6
|
-
|
7
|
-
subject{ SmartMutex.new }
|
8
|
-
|
9
|
-
def fly_solo
|
10
|
-
Thread.stub(:list).and_return(Array.new)
|
11
|
-
end
|
12
|
-
|
13
|
-
def run_with_the_pack
|
14
|
-
Thread.stub(:list).and_return([1,2,3,4])
|
15
|
-
end
|
16
|
-
|
17
|
-
context '#initialize' do
|
18
|
-
|
19
|
-
it 'creates a new mutex' do
|
20
|
-
Mutex.should_receive(:new).with(no_args())
|
21
|
-
SmartMutex.new
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
context '#alone?' do
|
26
|
-
|
27
|
-
it 'returns true when there is only one thread' do
|
28
|
-
fly_solo
|
29
|
-
subject.alone?.should be_true
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'returns false when there is more than one thread' do
|
33
|
-
run_with_the_pack
|
34
|
-
subject.alone?.should be_false
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
context '#lock' do
|
39
|
-
|
40
|
-
it 'does not lock when there is only one thread' do
|
41
|
-
fly_solo
|
42
|
-
|
43
|
-
mutex = Mutex.new
|
44
|
-
mutex.should_not_receive(:lock)
|
45
|
-
Mutex.should_receive(:new).with(no_args()).and_return(mutex)
|
46
|
-
|
47
|
-
subject.lock
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'locks when not locked and there is more than one thread' do
|
51
|
-
run_with_the_pack
|
52
|
-
|
53
|
-
mutex = Mutex.new
|
54
|
-
mutex.should_receive(:lock)
|
55
|
-
Mutex.should_receive(:new).with(no_args()).and_return(mutex)
|
56
|
-
|
57
|
-
subject.lock
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'raises an exception when locked and there is more than one thread' do
|
61
|
-
run_with_the_pack
|
62
|
-
subject.lock
|
63
|
-
lambda {
|
64
|
-
subject.lock
|
65
|
-
}.should raise_error(ThreadError)
|
66
|
-
end
|
67
|
-
|
68
|
-
it 'does not raise an exception when lock called twice and there is only one thread' do
|
69
|
-
fly_solo
|
70
|
-
subject.lock
|
71
|
-
lambda {
|
72
|
-
subject.lock
|
73
|
-
}.should_not raise_error
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'returns self' do
|
77
|
-
fly_solo
|
78
|
-
mutex = SmartMutex.new
|
79
|
-
mutex.lock.should eq mutex
|
80
|
-
|
81
|
-
run_with_the_pack
|
82
|
-
mutex.lock.should eq mutex
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
context '#locked?' do
|
87
|
-
|
88
|
-
it 'returns false when there is only one thread' do
|
89
|
-
fly_solo
|
90
|
-
subject.should_not be_locked
|
91
|
-
end
|
92
|
-
|
93
|
-
it 'returns true when locked and there is more than one thread' do
|
94
|
-
run_with_the_pack
|
95
|
-
subject.lock
|
96
|
-
subject.should be_locked
|
97
|
-
end
|
98
|
-
|
99
|
-
it 'returns false when not locked and there is more than one thread' do
|
100
|
-
run_with_the_pack
|
101
|
-
subject.should_not be_locked
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
context '#sleep' do
|
106
|
-
|
107
|
-
it 'sleeps when there is only one thread' do
|
108
|
-
fly_solo
|
109
|
-
Kernel.should_receive(:sleep).with(0.1).and_return(0.1)
|
110
|
-
subject.sleep(0.1)
|
111
|
-
end
|
112
|
-
|
113
|
-
it 'sleeps when locked and there is more than one thread' do
|
114
|
-
mutex = Mutex.new
|
115
|
-
mutex.should_receive(:sleep).with(0.1).and_return(0.1)
|
116
|
-
Mutex.should_receive(:new).with(no_args()).and_return(mutex)
|
117
|
-
|
118
|
-
run_with_the_pack
|
119
|
-
subject.lock
|
120
|
-
subject.sleep(0.1)
|
121
|
-
end
|
122
|
-
|
123
|
-
it 'raises an exception when not locked and there is more than one thread' do
|
124
|
-
run_with_the_pack
|
125
|
-
lambda {
|
126
|
-
subject.sleep(0.1)
|
127
|
-
}.should raise_error(ThreadError)
|
128
|
-
end
|
129
|
-
|
130
|
-
it 'returns the number of seconds slept' do
|
131
|
-
fly_solo
|
132
|
-
subject.sleep(1).should eq 1
|
133
|
-
|
134
|
-
run_with_the_pack
|
135
|
-
subject.lock
|
136
|
-
subject.sleep(1).should eq 1
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
context '#synchronize' do
|
141
|
-
|
142
|
-
it 'yields to the block when there is only one thread' do
|
143
|
-
fly_solo
|
144
|
-
@expected = false
|
145
|
-
subject.synchronize{ @expected = true }
|
146
|
-
@expected.should be_true
|
147
|
-
end
|
148
|
-
|
149
|
-
it 'locks when there is more than one thread' do
|
150
|
-
mutex = Mutex.new
|
151
|
-
mutex.should_receive(:synchronize).with(no_args())
|
152
|
-
Mutex.should_receive(:new).with(no_args()).and_return(mutex)
|
153
|
-
|
154
|
-
run_with_the_pack
|
155
|
-
subject.synchronize{ nil }
|
156
|
-
end
|
157
|
-
|
158
|
-
it 'yields to the block when there is more than one thread' do
|
159
|
-
run_with_the_pack
|
160
|
-
@expected = false
|
161
|
-
subject.synchronize{ @expected = true }
|
162
|
-
@expected.should be_true
|
163
|
-
end
|
164
|
-
|
165
|
-
it 'returns the result of the block' do
|
166
|
-
fly_solo
|
167
|
-
subject.synchronize{ 42 }.should eq 42
|
168
|
-
|
169
|
-
run_with_the_pack
|
170
|
-
subject.synchronize{ 42 }.should eq 42
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
context '#try_lock' do
|
175
|
-
|
176
|
-
it 'returns true when there is only one thread' do
|
177
|
-
fly_solo
|
178
|
-
subject.try_lock.should be_true
|
179
|
-
end
|
180
|
-
|
181
|
-
it 'returns true when the lock is obtained and there is more than one thread' do
|
182
|
-
run_with_the_pack
|
183
|
-
subject.try_lock.should be_true
|
184
|
-
end
|
185
|
-
|
186
|
-
it 'returns false when the lock is not obtained and there is more than one thread' do
|
187
|
-
run_with_the_pack
|
188
|
-
subject.lock
|
189
|
-
subject.try_lock.should be_false
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
context '#unlock' do
|
194
|
-
|
195
|
-
it 'does not unlock when there is only one thread' do
|
196
|
-
fly_solo
|
197
|
-
|
198
|
-
mutex = Mutex.new
|
199
|
-
mutex.should_not_receive(:unlock)
|
200
|
-
Mutex.should_receive(:new).with(no_args()).and_return(mutex)
|
201
|
-
|
202
|
-
subject.unlock
|
203
|
-
end
|
204
|
-
|
205
|
-
it 'unlocks when locked and there is more than one thread' do
|
206
|
-
run_with_the_pack
|
207
|
-
|
208
|
-
mutex = Mutex.new
|
209
|
-
mutex.should_receive(:unlock)
|
210
|
-
Mutex.should_receive(:new).with(no_args()).and_return(mutex)
|
211
|
-
|
212
|
-
subject.lock
|
213
|
-
subject.unlock
|
214
|
-
end
|
215
|
-
|
216
|
-
it 'raises an exception when not locked and there is more than one thread' do
|
217
|
-
run_with_the_pack
|
218
|
-
lambda {
|
219
|
-
subject.unlock
|
220
|
-
}.should raise_error(ThreadError)
|
221
|
-
end
|
222
|
-
|
223
|
-
it 'returns self' do
|
224
|
-
fly_solo
|
225
|
-
mutex = SmartMutex.new
|
226
|
-
mutex.unlock.should eq mutex
|
227
|
-
|
228
|
-
run_with_the_pack
|
229
|
-
mutex.lock
|
230
|
-
mutex.unlock.should eq mutex
|
231
|
-
end
|
232
|
-
end
|
233
|
-
end
|
234
|
-
end
|