concurrent-selectable 0.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.
- data/Rakefile +42 -0
- data/lib/concurrent/selectable.rb +33 -0
- data/lib/concurrent/selectable/channel.rb +86 -0
- data/lib/concurrent/selectable/common.rb +78 -0
- data/lib/concurrent/selectable/latch.rb +80 -0
- data/lib/concurrent/selectable/semaphore.rb +91 -0
- data/test/test_all.rb +3 -0
- data/test/test_channel.rb +23 -0
- data/test/test_latch.rb +23 -0
- data/test/test_semaphore.rb +23 -0
- metadata +54 -0
data/Rakefile
ADDED
@@ -0,0 +1,42 @@
|
|
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
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# concurrent/selectable - Synchronization primitives supporting IO.select
|
2
|
+
#
|
3
|
+
# Copyright 2008 MenTaLguY <mental@rydia.net>
|
4
|
+
#
|
5
|
+
# All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are met:
|
9
|
+
#
|
10
|
+
# * Redistributions of source code must retain the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer.
|
12
|
+
# * Redistributions in binary form must reproduce the above copyright notice
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
14
|
+
# and/or other materials provided with the distribution.
|
15
|
+
# * The names of the authors may not be used to endorse or promote products
|
16
|
+
# derived from this software without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
21
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
22
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
23
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
24
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
25
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
26
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
27
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
28
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
|
30
|
+
require 'concurrent/selectable/channel'
|
31
|
+
require 'concurrent/selectable/latch'
|
32
|
+
require 'concurrent/selectable/semaphore'
|
33
|
+
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# concurrent/selectable/channel - IO-Selectable channel
|
2
|
+
#
|
3
|
+
# Copyright 2008 MenTaLguY <mental@rydia.net>
|
4
|
+
#
|
5
|
+
# All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are met:
|
9
|
+
#
|
10
|
+
# * Redistributions of source code must retain the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer.
|
12
|
+
# * Redistributions in binary form must reproduce the above copyright notice
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
14
|
+
# and/or other materials provided with the distribution.
|
15
|
+
# * The names of the authors may not be used to endorse or promote products
|
16
|
+
# derived from this software without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
21
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
22
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
23
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
24
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
25
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
26
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
27
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
28
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
|
30
|
+
require 'thread'
|
31
|
+
begin
|
32
|
+
require 'fastthread'
|
33
|
+
rescue LoadError
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'concurrent/selectable/common'
|
37
|
+
|
38
|
+
module Concurrent
|
39
|
+
module Selectable
|
40
|
+
|
41
|
+
# A thread-safe FIFO channel of Ruby objects which can be selected on as if it
|
42
|
+
# were an IO object.
|
43
|
+
class Channel < Base
|
44
|
+
def initialize
|
45
|
+
super()
|
46
|
+
@lock = ::Mutex.new
|
47
|
+
@channel = ::Queue.new
|
48
|
+
end
|
49
|
+
|
50
|
+
# Attempts to get a value from the channel and returns it, blocking if none
|
51
|
+
# is available and +blocking+ is true. If +blocking+ is false, then
|
52
|
+
# +default_value+ is returned if no value is currently available.
|
53
|
+
def get(blocking=true, default_value=nil)
|
54
|
+
loop do
|
55
|
+
@lock.synchronize do
|
56
|
+
size = @channel.size
|
57
|
+
if size.nonzero?
|
58
|
+
value = @channel.deq
|
59
|
+
internal_reset if size == 1 # i.e. if we removed the last remaining
|
60
|
+
return value
|
61
|
+
end
|
62
|
+
end
|
63
|
+
return default_value unless blocking
|
64
|
+
wait
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Places +value+ on the channel.
|
69
|
+
def put(value)
|
70
|
+
@lock.synchronize do
|
71
|
+
internal_set if @channel.empty?
|
72
|
+
@channel.enq value
|
73
|
+
end
|
74
|
+
end
|
75
|
+
alias_method :<<, :put
|
76
|
+
|
77
|
+
# Returns true if the channel is currently empty (additional external
|
78
|
+
# synchronization is normally required if other threads can manipulate
|
79
|
+
# the channel)
|
80
|
+
def empty?
|
81
|
+
@channel.empty?
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# concurrent/selectable/common - Common bits for IO-Selectable synchronization
|
2
|
+
#
|
3
|
+
# Copyright 2008 MenTaLguY <mental@rydia.net>
|
4
|
+
#
|
5
|
+
# All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are met:
|
9
|
+
#
|
10
|
+
# * Redistributions of source code must retain the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer.
|
12
|
+
# * Redistributions in binary form must reproduce the above copyright notice
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
14
|
+
# and/or other materials provided with the distribution.
|
15
|
+
# * The names of the authors may not be used to endorse or promote products
|
16
|
+
# derived from this software without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
21
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
22
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
23
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
24
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
25
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
26
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
27
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
28
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
|
30
|
+
require 'thread'
|
31
|
+
begin
|
32
|
+
require 'fastthread'
|
33
|
+
rescue LoadError
|
34
|
+
end
|
35
|
+
|
36
|
+
module Concurrent
|
37
|
+
module Selectable
|
38
|
+
|
39
|
+
# Raised if a wait exceeds a given timeout
|
40
|
+
class TimeoutError < RuntimeError
|
41
|
+
end
|
42
|
+
|
43
|
+
# Base class for selectable primitives
|
44
|
+
class Base
|
45
|
+
def initialize #:nodoc:
|
46
|
+
@read, @write = IO.pipe
|
47
|
+
end
|
48
|
+
|
49
|
+
# Waits for the primitive to become available/signaled, with the given
|
50
|
+
# +timeout+ (see IO.select). If +timeout+ is given and is not +nil+, then
|
51
|
+
# TimeoutError will be raised if the timeout is exceeded.
|
52
|
+
def wait(timeout=nil)
|
53
|
+
ready = IO.select([@read], nil, nil, timeout)
|
54
|
+
raise TimeoutError, "wait timed out" unless ready
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
# Converts the primitive to an IO object; the object is only safe to
|
59
|
+
# test whether it is ready for reading; DO NOT read from the returned
|
60
|
+
# IO object yourself.
|
61
|
+
def to_io
|
62
|
+
@read
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
def internal_set
|
67
|
+
@write.write 'x'
|
68
|
+
self
|
69
|
+
end
|
70
|
+
|
71
|
+
def internal_reset
|
72
|
+
@read.read 1
|
73
|
+
self
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# concurrent/selectable/latch - IO-Selectable latch
|
2
|
+
#
|
3
|
+
# Copyright 2008 MenTaLguY <mental@rydia.net>
|
4
|
+
#
|
5
|
+
# All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are met:
|
9
|
+
#
|
10
|
+
# * Redistributions of source code must retain the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer.
|
12
|
+
# * Redistributions in binary form must reproduce the above copyright notice
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
14
|
+
# and/or other materials provided with the distribution.
|
15
|
+
# * The names of the authors may not be used to endorse or promote products
|
16
|
+
# derived from this software without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
21
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
22
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
23
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
24
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
25
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
26
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
27
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
28
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
|
30
|
+
require 'thread'
|
31
|
+
begin
|
32
|
+
require 'fastthread'
|
33
|
+
rescue LoadError
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'concurrent/selectable/common'
|
37
|
+
|
38
|
+
module Concurrent
|
39
|
+
module Selectable
|
40
|
+
|
41
|
+
# A latch is a toggle which starts out unset. Threads can wait for the
|
42
|
+
# latch to become set by calling Latch#wait (inherited from Base). The
|
43
|
+
# latch can be reset to its intial state using Latch#reset.
|
44
|
+
class Latch < Base
|
45
|
+
def initialize
|
46
|
+
super()
|
47
|
+
@lock = ::Mutex.new
|
48
|
+
@set = false
|
49
|
+
end
|
50
|
+
|
51
|
+
# Sets the latch, allowing any current and future waiting threads to
|
52
|
+
# continue
|
53
|
+
def set
|
54
|
+
@lock.synchronize do
|
55
|
+
internal_set unless @set
|
56
|
+
@set = true
|
57
|
+
end
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
# Non-blocking test whether the latch is currently set (additional
|
62
|
+
# external synchronization will usually be required if the latch can be
|
63
|
+
# set or reset by other threads)
|
64
|
+
def set?
|
65
|
+
@lock.synchronize { @set }
|
66
|
+
end
|
67
|
+
|
68
|
+
# Resets the latch, blocking any subsequent waiting threads until the
|
69
|
+
# latch is set again
|
70
|
+
def reset
|
71
|
+
@lock.synchronize do
|
72
|
+
internal_reset if @set
|
73
|
+
@set = false
|
74
|
+
end
|
75
|
+
self
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# concurrent/selectable/semaphore - IO-Selectable semaphore
|
2
|
+
#
|
3
|
+
# Copyright 2008 MenTaLguY <mental@rydia.net>
|
4
|
+
#
|
5
|
+
# All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are met:
|
9
|
+
#
|
10
|
+
# * Redistributions of source code must retain the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer.
|
12
|
+
# * Redistributions in binary form must reproduce the above copyright notice
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
14
|
+
# and/or other materials provided with the distribution.
|
15
|
+
# * The names of the authors may not be used to endorse or promote products
|
16
|
+
# derived from this software without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
21
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
22
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
23
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
24
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
25
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
26
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
27
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
28
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
|
30
|
+
require 'thread'
|
31
|
+
begin
|
32
|
+
require 'fastthread'
|
33
|
+
rescue LoadError
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'concurrent/selectable/common'
|
37
|
+
|
38
|
+
module Concurrent
|
39
|
+
module Selectable
|
40
|
+
|
41
|
+
# A Semaphore is a counter which can be atomically incremented and decremented;
|
42
|
+
# attempts to decrement the counter below zero will block.
|
43
|
+
class Semaphore < Base
|
44
|
+
# Creates a semaphore with the given initial +count+
|
45
|
+
def initialize(count=0)
|
46
|
+
super()
|
47
|
+
@lock = ::Mutex.new
|
48
|
+
@count = count
|
49
|
+
end
|
50
|
+
|
51
|
+
# Decrements the semaphore, blocking if its count is already zero and
|
52
|
+
# +blocking+ is true.
|
53
|
+
def get(blocking=true)
|
54
|
+
loop do
|
55
|
+
@lock.synchronize do
|
56
|
+
if @count.nonzero?
|
57
|
+
@count -= 1
|
58
|
+
internal_reset if @count.zero?
|
59
|
+
return self
|
60
|
+
end
|
61
|
+
end
|
62
|
+
return nil unless blocking
|
63
|
+
wait
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Increments the semaphore
|
68
|
+
def put
|
69
|
+
@lock.synchronize do
|
70
|
+
internal_set if @count.zero?
|
71
|
+
@count += 1
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns true if the count is currently zero (additional external
|
76
|
+
# synchronization is usually required if other threads can modify the
|
77
|
+
# semaphore)
|
78
|
+
def zero?
|
79
|
+
@lock.synchronize { @count.zero? }
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns true if the count is currently nonzero (additional external
|
83
|
+
# synchronization is usually required if other threads can modify the
|
84
|
+
# semaphore)
|
85
|
+
def nonzero?
|
86
|
+
@lock.synchronize { @count.nonzero? }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
data/test/test_all.rb
ADDED
@@ -0,0 +1,23 @@
|
|
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
|
data/test/test_latch.rb
ADDED
@@ -0,0 +1,23 @@
|
|
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
|
@@ -0,0 +1,23 @@
|
|
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
|
metadata
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.11
|
3
|
+
specification_version: 1
|
4
|
+
name: concurrent-selectable
|
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
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email:
|
12
|
+
homepage:
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
authors:
|
29
|
+
- MenTaLguY <mental@rydia.net>
|
30
|
+
files:
|
31
|
+
- Rakefile
|
32
|
+
- test/test_latch.rb
|
33
|
+
- test/test_all.rb
|
34
|
+
- test/test_semaphore.rb
|
35
|
+
- test/test_channel.rb
|
36
|
+
- lib/concurrent/selectable.rb
|
37
|
+
- lib/concurrent/selectable/latch.rb
|
38
|
+
- lib/concurrent/selectable/common.rb
|
39
|
+
- lib/concurrent/selectable/semaphore.rb
|
40
|
+
- lib/concurrent/selectable/channel.rb
|
41
|
+
test_files:
|
42
|
+
- test/test_all.rb
|
43
|
+
rdoc_options: []
|
44
|
+
|
45
|
+
extra_rdoc_files: []
|
46
|
+
|
47
|
+
executables: []
|
48
|
+
|
49
|
+
extensions: []
|
50
|
+
|
51
|
+
requirements: []
|
52
|
+
|
53
|
+
dependencies: []
|
54
|
+
|