concurrent-selectable 0.1 → 0.1.1

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.
@@ -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