concurrent-selectable 0.1 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -64,6 +64,7 @@ class Channel < Base
64
64
  wait
65
65
  end
66
66
  end
67
+ alias_method :receive, :get
67
68
 
68
69
  # Places +value+ on the channel.
69
70
  def put(value)
@@ -62,6 +62,16 @@ class Base
62
62
  @read
63
63
  end
64
64
 
65
+ # Manually releases the IO resources associated with the primitive
66
+ def close
67
+ [ @read, @write ].each do |port|
68
+ begin
69
+ port.close
70
+ rescue Exception
71
+ end
72
+ end
73
+ end
74
+
65
75
  private
66
76
  def internal_set
67
77
  @write.write 'x'
@@ -48,9 +48,21 @@ class Semaphore < Base
48
48
  @count = count
49
49
  end
50
50
 
51
+ # Increments the semaphore
52
+ def signal
53
+ @lock.synchronize do
54
+ internal_set if @count.zero?
55
+ @count += 1
56
+ end
57
+ self
58
+ end
59
+ alias_method :put, :signal
60
+ alias_method :up, :signal
61
+ alias_method :v, :signal
62
+
51
63
  # Decrements the semaphore, blocking if its count is already zero and
52
64
  # +blocking+ is true.
53
- def get(blocking=true)
65
+ def wait(blocking=true)
54
66
  loop do
55
67
  @lock.synchronize do
56
68
  if @count.nonzero?
@@ -60,17 +72,22 @@ class Semaphore < Base
60
72
  end
61
73
  end
62
74
  return nil unless blocking
63
- wait
75
+ super()
64
76
  end
65
77
  end
78
+ alias_method :get, :wait
79
+ alias_method :down, :wait
80
+ alias_method :p, :wait
66
81
 
67
- # Increments the semaphore
68
- def put
69
- @lock.synchronize do
70
- internal_set if @count.zero?
71
- @count += 1
82
+ def exclusive
83
+ wait
84
+ begin
85
+ yield
86
+ ensure
87
+ signal
72
88
  end
73
89
  end
90
+ alias_method :synchronize, :exclusive
74
91
 
75
92
  # Returns true if the count is currently zero (additional external
76
93
  # synchronization is usually required if other threads can modify the
@@ -0,0 +1,45 @@
1
+ require 'concurrent/selectable/channel'
2
+
3
+ SChannel = Concurrent::Selectable::Channel
4
+
5
+ describe SChannel do
6
+ before :each do
7
+ @channel = SChannel.new
8
+ end
9
+
10
+ it "should be convertable to an IO object" do
11
+ @channel.to_io.should be_an_instance_of(IO)
12
+ end
13
+
14
+ it "should allow values to be written with << and received with receive" do
15
+ @channel << :blah
16
+ t = Thread.new { sleep 2 ; @channel << nil }
17
+ @channel.receive.should == :blah
18
+ end
19
+
20
+ it "should allow values to be written with put and received with get" do
21
+ @channel.put :blah
22
+ t = Thread.new { sleep 2 ; @channel.put nil }
23
+ @channel.get.should == :blah
24
+ end
25
+
26
+ it "should block while a value is not available" do
27
+ t = Thread.new { sleep 2 ; @channel << :foo }
28
+ @channel.receive.should == :foo
29
+ end
30
+
31
+ it "should not be readable when empty empty" do
32
+ IO.select([@channel], nil, nil, 0).should be_nil
33
+ end
34
+
35
+ it "should be readable while it has values" do
36
+ @channel << :blah
37
+ IO.select([@channel], nil, nil, 0).should == [[@channel], [], []]
38
+ end
39
+
40
+ it "should not be readable after it has been emptied" do
41
+ @channel << :blah
42
+ @channel.receive
43
+ IO.select([@channel], nil, nil, 0).should be_nil
44
+ end
45
+ end
@@ -0,0 +1,28 @@
1
+ require 'concurrent/selectable/latch'
2
+
3
+ Latch = Concurrent::Selectable::Latch
4
+
5
+ describe Latch do
6
+ before :each do
7
+ @latch = Latch.new
8
+ end
9
+
10
+ it "should be convertable to an IO object" do
11
+ @latch.to_io.should be_an_instance_of(IO)
12
+ end
13
+
14
+ it "should not be readable when it is not set" do
15
+ IO.select([@latch], nil, nil, 0).should be_nil
16
+ end
17
+
18
+ it "should be readable when it is set" do
19
+ @latch.set
20
+ IO.select([@latch], nil, nil, 0).should == [[@latch], [], []]
21
+ end
22
+
23
+ it "should not be readable after it is reset" do
24
+ @latch.set
25
+ @latch.reset
26
+ IO.select([@latch], nil, nil, 0).should be_nil
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ require 'concurrent/selectable/semaphore'
2
+
3
+ CSemaphore = Concurrent::Selectable::Semaphore
4
+
5
+ describe CSemaphore do
6
+ before :each do
7
+ @semaphore = CSemaphore.new
8
+ end
9
+
10
+ it "should be convertable to an IO object" do
11
+ @semaphore.to_io.should be_an_instance_of(IO)
12
+ end
13
+
14
+ it "should not be readable when it has a zero count" do
15
+ IO.select([@semaphore], nil, nil, 0).should be_nil
16
+ end
17
+
18
+ it "should be readable after it has been incremented" do
19
+ @semaphore.put
20
+ IO.select([@semaphore], nil, nil, 0).should == [[@semaphore], [], []]
21
+ end
22
+
23
+ it "should not be readable after it has been decremented again" do
24
+ @semaphore.put
25
+ @semaphore.get
26
+ IO.select([@semaphore], nil, nil, 0).should be_nil
27
+ end
28
+ end
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.8.11
2
+ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: concurrent-selectable
5
5
  version: !ruby/object:Gem::Version
6
- version: "0.1"
7
- date: 2008-01-27 00:00:00 -05:00
8
- summary: Synchronization primitives with selectable IO channels
6
+ version: 0.1.1
7
+ date: 2008-06-03 00:00:00 -04:00
8
+ summary: Synchronization primitives for event-driven IO
9
9
  require_paths:
10
10
  - lib
11
11
  email:
@@ -25,21 +25,20 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
25
25
  platform: ruby
26
26
  signing_key:
27
27
  cert_chain:
28
+ post_install_message:
28
29
  authors:
29
30
  - MenTaLguY <mental@rydia.net>
30
31
  files:
31
- - Rakefile
32
- - test/test_latch.rb
33
- - test/test_all.rb
34
- - test/test_semaphore.rb
35
- - test/test_channel.rb
32
+ - spec/selectable/channel_spec.rb
33
+ - spec/selectable/latch_spec.rb
34
+ - spec/selectable/semaphore_spec.rb
36
35
  - lib/concurrent/selectable.rb
37
- - lib/concurrent/selectable/latch.rb
36
+ - lib/concurrent/selectable/channel.rb
38
37
  - lib/concurrent/selectable/common.rb
38
+ - lib/concurrent/selectable/latch.rb
39
39
  - lib/concurrent/selectable/semaphore.rb
40
- - lib/concurrent/selectable/channel.rb
41
- test_files:
42
- - test/test_all.rb
40
+ test_files: []
41
+
43
42
  rdoc_options: []
44
43
 
45
44
  extra_rdoc_files: []
data/Rakefile DELETED
@@ -1,42 +0,0 @@
1
- require 'rake'
2
- require 'rake/testtask'
3
- require 'rake/rdoctask'
4
- require 'rake/gempackagetask'
5
- require 'rake/clean'
6
-
7
- GEM_VERSION = "0.1"
8
-
9
- Rake::RDocTask.new do |task|
10
- task.rdoc_files.add [ 'lib/**/*.rb' ]
11
- end
12
-
13
- task :clobber => [ :clean ]
14
-
15
- Rake::TestTask.new do |task|
16
- task.ruby_opts << '-rrubygems'
17
- task.libs << 'lib'
18
- task.libs << 'test'
19
- task.test_files = [ "test/test_all.rb" ]
20
- task.verbose = true
21
- end
22
-
23
- gemspec = Gem::Specification.new do |gemspec|
24
- gemspec.name = "concurrent-selectable"
25
- gemspec.version = GEM_VERSION
26
- gemspec.author = "MenTaLguY <mental@rydia.net>"
27
- gemspec.summary = "Synchronization primitives with selectable IO channels"
28
- gemspec.test_file = 'test/test_all.rb'
29
- gemspec.files = FileList[ 'Rakefile', 'test/*.rb', 'lib/**/*.rb' ]
30
- gemspec.require_paths = [ 'lib' ]
31
- gemspec.has_rdoc = true
32
- gemspec.platform = Gem::Platform::RUBY
33
- end
34
-
35
- task :package => [ :clean, :test ]
36
- Rake::GemPackageTask.new( gemspec ) do |task|
37
- task.gem_spec = gemspec
38
- task.need_tar = true
39
- end
40
-
41
- task :default => [ :clean, :test ]
42
-
@@ -1,3 +0,0 @@
1
- require 'test_channel.rb'
2
- require 'test_latch.rb'
3
- require 'test_semaphore.rb'
@@ -1,23 +0,0 @@
1
- require 'test/unit'
2
- require 'concurrent/selectable/channel'
3
-
4
- SChannel = Concurrent::Selectable::Channel
5
-
6
- class TestChannel < Test::Unit::TestCase
7
- def test_to_io
8
- channel = SChannel.new
9
- assert_instance_of IO, channel.to_io
10
- end
11
-
12
- def test_select
13
- channel = SChannel.new
14
- ready = IO.select([channel], nil, nil, 0.01)
15
- assert !ready
16
- channel.put :blah
17
- ready = IO.select([channel], nil, nil, 0.01)
18
- assert ready
19
- channel.get
20
- ready = IO.select([channel], nil, nil, 0.01)
21
- assert !ready
22
- end
23
- end
@@ -1,23 +0,0 @@
1
- require 'test/unit'
2
- require 'concurrent/selectable/latch'
3
-
4
- Latch = Concurrent::Selectable::Latch
5
-
6
- class TestLatch < Test::Unit::TestCase
7
- def test_to_io
8
- latch = Latch.new
9
- assert_instance_of IO, latch.to_io
10
- end
11
-
12
- def test_select
13
- latch = Latch.new
14
- ready = IO.select([latch], nil, nil, 0.01)
15
- assert !ready
16
- latch.set
17
- ready = IO.select([latch], nil, nil, 0.01)
18
- assert ready
19
- latch.reset
20
- ready = IO.select([latch], nil, nil, 0.01)
21
- assert !ready
22
- end
23
- end
@@ -1,23 +0,0 @@
1
- require 'test/unit'
2
- require 'concurrent/selectable/semaphore'
3
-
4
- Semaphore = Concurrent::Selectable::Semaphore
5
-
6
- class TestSemaphore < Test::Unit::TestCase
7
- def test_to_io
8
- semaphore = Semaphore.new
9
- assert_instance_of IO, semaphore.to_io
10
- end
11
-
12
- def test_select
13
- semaphore = Semaphore.new
14
- ready = IO.select([semaphore], nil, nil, 0.01)
15
- assert !ready
16
- semaphore.put
17
- ready = IO.select([semaphore], nil, nil, 0.01)
18
- assert ready
19
- semaphore.get
20
- ready = IO.select([semaphore], nil, nil, 0.01)
21
- assert !ready
22
- end
23
- end