sleepy_penguin 1.4.0 → 2.0.0

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/test/test_eventfd.rb CHANGED
@@ -14,6 +14,7 @@ class TestEventFD < Test::Unit::TestCase
14
14
  assert_kind_of Integer, EventFD::CLOEXEC
15
15
  defined?(EventFD::SEMAPHORE) and
16
16
  assert_kind_of Integer, EventFD::SEMAPHORE
17
+ assert_equal 0xfffffffffffffffe, EventFD::MAX
17
18
  end
18
19
 
19
20
  def test_new
@@ -27,6 +28,15 @@ class TestEventFD < Test::Unit::TestCase
27
28
  assert_equal(Fcntl::O_NONBLOCK, flags)
28
29
  end if defined?(EventFD::NONBLOCK)
29
30
 
31
+ def test_new_nonblock_cloexec_sym
32
+ efd = EventFD.new(0, [:NONBLOCK,:CLOEXEC])
33
+ flags = efd.fcntl(Fcntl::F_GETFL) & Fcntl::O_NONBLOCK
34
+ assert_equal(Fcntl::O_NONBLOCK, flags)
35
+
36
+ flags = efd.fcntl(Fcntl::F_GETFD) & Fcntl::FD_CLOEXEC
37
+ assert_equal(Fcntl::FD_CLOEXEC, flags)
38
+ end if defined?(EventFD::NONBLOCK) && defined?(EventFD::CLOEXEC)
39
+
30
40
  def test_new_cloexec
31
41
  efd = EventFD.new(0, EventFD::CLOEXEC)
32
42
  flags = efd.fcntl(Fcntl::F_GETFD) & Fcntl::FD_CLOEXEC
@@ -35,14 +45,22 @@ class TestEventFD < Test::Unit::TestCase
35
45
 
36
46
  def test_incr_value
37
47
  efd = EventFD.new(0)
38
- assert_nil efd.incr(1)
48
+ assert_equal true, efd.incr(1)
39
49
  assert_equal 1, efd.value
40
50
 
41
- assert_raises(Errno::EAGAIN) { efd.value_nonblock }
42
- assert_nil efd.incr(9)
43
- assert_equal 9, efd.value_nonblock
51
+ assert_nil efd.value(true)
52
+ assert_equal true, efd.incr(9)
53
+ assert_equal 9, efd.value(true)
54
+
55
+ assert_equal true, efd.incr(0xfffffffffffffffe)
56
+ assert_equal false, efd.incr(1, true)
57
+ end
44
58
 
45
- assert_nil efd.incr(0xfffffffffffffffe)
46
- assert_raises(Errno::EAGAIN) { efd.incr_nonblock 1 }
59
+ def test_incr_value_semaphore
60
+ efd = EventFD.new(6, :SEMAPHORE)
61
+ 6.times { assert_equal 1, efd.value }
62
+ assert_nil efd.value(true)
63
+ assert_equal true, efd.incr(1)
64
+ assert_equal 1, efd.value
47
65
  end
48
66
  end if defined?(SleepyPenguin::EventFD)
data/test/test_inotify.rb CHANGED
@@ -1,17 +1,35 @@
1
1
  require 'test/unit'
2
2
  require 'fcntl'
3
3
  require 'tempfile'
4
+ require 'set'
4
5
  $-w = true
5
6
  require 'sleepy_penguin'
6
7
 
7
8
  class TestInotify < Test::Unit::TestCase
8
9
  include SleepyPenguin
10
+ attr_reader :ino
11
+
12
+ def teardown
13
+ ObjectSpace.each_object(Inotify) { |io| io.close unless io.closed? }
14
+ ObjectSpace.each_object(Tempfile) { |io| io.close unless io.closed? }
15
+ end
9
16
 
10
17
  def test_new
11
- ino = Inotify.new
18
+ @ino = Inotify.new
12
19
  assert_kind_of(IO, ino)
13
20
  end
14
21
 
22
+ def test_constants
23
+ (Inotify.constants - IO.constants).each do |const|
24
+ case const.to_sym
25
+ when :Event, :Enumerator
26
+ else
27
+ nr = Inotify.const_get(const)
28
+ assert nr <= 0xffffffff, "#{const}=#{nr}"
29
+ end
30
+ end
31
+ end
32
+
15
33
  def test_dup
16
34
  a = Inotify.new
17
35
  b = a.dup
@@ -59,4 +77,65 @@ class TestInotify < Test::Unit::TestCase
59
77
  assert_equal second_id, ino.take.object_id
60
78
  assert_nil ino.take(true)
61
79
  end
80
+
81
+ def test_add_take_symbols
82
+ ino = Inotify.new :CLOEXEC
83
+ tmp1 = Tempfile.new 'take'
84
+ tmp2 = Tempfile.new 'take'
85
+ wd = ino.add_watch File.dirname(tmp1.path), :MOVE
86
+ assert_kind_of Integer, wd
87
+ File.rename tmp1.path, tmp2.path
88
+ event = ino.take
89
+ assert_equal wd, event.wd
90
+ assert_kind_of Inotify::Event, event
91
+ assert_equal File.basename(tmp1.path), event.name
92
+ others = ino.instance_variable_get(:@inotify_tmp)
93
+ assert_kind_of Array, others
94
+ assert_equal 1, others.size
95
+ assert_equal File.basename(tmp2.path), others[0].name
96
+ assert_equal [ :MOVED_FROM ], event.events
97
+ assert_equal [ :MOVED_TO ], others[0].events
98
+ assert_equal wd, others[0].wd
99
+ second_id = others[0].object_id
100
+ assert_equal second_id, ino.take.object_id
101
+ assert_nil ino.take(true)
102
+ end
103
+
104
+ def test_each
105
+ ino = Inotify.new :CLOEXEC
106
+ tmp1 = Tempfile.new 'take'
107
+ wd = ino.add_watch tmp1.path, :OPEN
108
+ assert_kind_of Integer, wd
109
+ nr = 5
110
+ o = File.open(tmp1.path)
111
+ ino.each do |event|
112
+ assert_equal [:OPEN], event.events
113
+ break if (nr -= 1) == 0
114
+ o = File.open(tmp1.path)
115
+ end
116
+ assert_equal 0, nr
117
+ end
118
+
119
+ def test_close_threadable
120
+ ino = Inotify.new
121
+ tmp = []
122
+ thr = Thread.new do
123
+ until ino.closed?
124
+ tmp << Time.now
125
+ Thread.pass
126
+ end
127
+ end
128
+ t0 = Time.now
129
+ ino.close
130
+ t1 = Time.now
131
+ between = []
132
+ thr.join
133
+ tmp.each do |t|
134
+ if t > t0 && t < t1
135
+ between << t
136
+ end
137
+ end
138
+ assert tmp.size > 0, "tmp.size=#{tmp.size}"
139
+ assert between.size > 0, "between.size=#{between.size}"
140
+ end if RUBY_VERSION.to_f >= 1.9
62
141
  end
@@ -0,0 +1,94 @@
1
+ require 'test/unit'
2
+ require "dl"
3
+ begin
4
+ require "dl/func"
5
+ rescue LoadError
6
+ end
7
+ $-w = true
8
+ require 'sleepy_penguin'
9
+
10
+ class TestSignalFD < Test::Unit::TestCase
11
+ include SleepyPenguin
12
+
13
+ def setup
14
+ @sfd = nil
15
+ trap(:USR1, "IGNORE")
16
+ trap(:USR2, "IGNORE")
17
+ end
18
+
19
+ def teardown
20
+ @sfd.close if @sfd && ! @sfd.closed?
21
+ trap(:USR1, "DEFAULT")
22
+ trap(:USR2, "DEFAULT")
23
+ end
24
+
25
+ def test_rt_constants
26
+ assert [33,34].include?(SignalFD::RTMIN)
27
+ assert_equal 64, SignalFD::RTMAX
28
+ end
29
+
30
+ def test_new_with_flags
31
+ @sfd = SignalFD.new(%w(USR1), [:CLOEXEC,:NONBLOCK])
32
+ assert_instance_of SignalFD, @sfd
33
+ end if defined?(SignalFD::CLOEXEC) && defined?(SignalFD::NONBLOCK)
34
+
35
+ def test_new_with_sym_flag
36
+ @sfd = SignalFD.new(%w(USR1), :CLOEXEC)
37
+ assert_instance_of SignalFD, @sfd
38
+ end if defined?(SignalFD::CLOEXEC)
39
+
40
+ def test_take
41
+ @sfd = SignalFD.new(%w(USR1), 0)
42
+ pid = fork { sleep 0.01; Process.kill(:USR1, Process.ppid) }
43
+ siginfo = @sfd.take
44
+ assert_equal Signal.list["USR1"], siginfo.signo
45
+ assert_equal pid, siginfo.pid
46
+ assert Process.waitpid2(pid)[1].success?
47
+ end if RUBY_VERSION =~ %r{\A1\.9}
48
+
49
+ def test_take_nonblock
50
+ @sfd = SignalFD.new(%w(USR1), :NONBLOCK)
51
+ assert_nil @sfd.take(true)
52
+ assert_nil IO.select [ @sfd ], nil, nil, 0
53
+ pid = fork { sleep 0.01; Process.kill(:USR1, Process.ppid) }
54
+ siginfo = @sfd.take(true)
55
+ if siginfo
56
+ assert_equal Signal.list["USR1"], siginfo.signo
57
+ assert_equal pid, siginfo.pid
58
+ else
59
+ warn "WARNING: SignalFD#take(nonblock=true) broken"
60
+ end
61
+ assert Process.waitpid2(pid)[1].success?
62
+ end if RUBY_VERSION =~ %r{\A1\.9}
63
+
64
+ def test_update
65
+ assert_nothing_raised do
66
+ @sfd = SignalFD.new
67
+ @sfd.update! Signal.list["USR1"]
68
+ @sfd.update! [ "USR1", Signal.list["USR2"] ]
69
+ @sfd.update! [ "USR1", :USR2 ]
70
+ @sfd.update! [ Signal.list["USR1"], Signal.list["USR2"] ]
71
+ end
72
+ end
73
+
74
+ def test_with_sigqueue
75
+ sig = Signal.list["USR2"]
76
+ @sfd = SignalFD.new(:USR2)
77
+ libc = DL::Handle.new("libc.so.6")
78
+ if defined?(DL::Function)
79
+ sigqueue = libc["sigqueue"]
80
+ sigqueue = DL::CFunc.new(sigqueue, DL::TYPE_INT, "sigqueue")
81
+ args = [DL::TYPE_INT, DL::TYPE_INT,DL::TYPE_INT]
82
+ sigqueue = DL::Function.new(sigqueue, args, DL::TYPE_INT)
83
+ else
84
+ sigqueue = libc["sigqueue", "IIII"]
85
+ end
86
+ pid = fork { sleep 0.01; sigqueue.call(Process.ppid, sig, 666) }
87
+ siginfo = @sfd.take
88
+ assert_equal sig, siginfo.signo
89
+ assert_equal pid, siginfo.pid
90
+ assert Process.waitpid2(pid)[1].success?
91
+ assert_equal 666, siginfo.ptr
92
+ assert_equal 666, siginfo.int
93
+ end if RUBY_VERSION =~ %r{\A1\.9}
94
+ end if defined?(SleepyPenguin::SignalFD)
@@ -0,0 +1,32 @@
1
+ require 'test/unit'
2
+ $-w = true
3
+ require 'sleepy_penguin'
4
+
5
+ class TestSignalFDSigInfo < Test::Unit::TestCase
6
+ include SleepyPenguin
7
+
8
+ def test_members
9
+ members = SignalFD::SigInfo::MEMBERS
10
+ assert_equal 16, members.size
11
+ a = SignalFD::SigInfo.new
12
+ members.each { |k| assert_equal 0, a.__send__(k) }
13
+ end
14
+
15
+ def test_equality
16
+ a = SignalFD::SigInfo.new
17
+ b = SignalFD::SigInfo.new
18
+ assert_equal a, b
19
+
20
+ c = Class.new(SignalFD::SigInfo).new
21
+ assert_equal a, c
22
+ assert c != c.to_hash
23
+ end
24
+
25
+ def test_to_hash
26
+ hash = SignalFD::SigInfo.new.to_hash
27
+ assert_instance_of Hash, hash
28
+ members = SignalFD::SigInfo::MEMBERS
29
+ assert_equal members.size, hash.size
30
+ members.each { |k| assert_equal 0, hash[k] }
31
+ end
32
+ end if defined?(SleepyPenguin::SignalFD)
data/test/test_timerfd.rb CHANGED
@@ -13,26 +13,56 @@ class TestTimerFD < Test::Unit::TestCase
13
13
  end
14
14
 
15
15
  def test_create
16
- tfd = TimerFD.create
16
+ tfd = TimerFD.new
17
17
  assert_kind_of(IO, tfd)
18
18
  end
19
19
 
20
20
  def test_create_nonblock
21
- tfd = TimerFD.create(TimerFD::REALTIME, TimerFD::NONBLOCK)
21
+ tfd = TimerFD.new(TimerFD::REALTIME, TimerFD::NONBLOCK)
22
+ flags = tfd.fcntl(Fcntl::F_GETFL) & Fcntl::O_NONBLOCK
23
+ assert_equal(Fcntl::O_NONBLOCK, flags)
24
+ end if defined?(TimerFD::NONBLOCK)
25
+
26
+ def test_create_nonblock_sym
27
+ tfd = TimerFD.new(:REALTIME, :NONBLOCK)
22
28
  flags = tfd.fcntl(Fcntl::F_GETFL) & Fcntl::O_NONBLOCK
23
29
  assert_equal(Fcntl::O_NONBLOCK, flags)
24
30
  end if defined?(TimerFD::NONBLOCK)
25
31
 
26
32
  def test_create_cloexec
27
- tfd = TimerFD.create(TimerFD::REALTIME, TimerFD::CLOEXEC)
33
+ tfd = TimerFD.new(TimerFD::REALTIME, TimerFD::CLOEXEC)
28
34
  flags = tfd.fcntl(Fcntl::F_GETFD) & Fcntl::FD_CLOEXEC
29
35
  assert_equal(Fcntl::FD_CLOEXEC, flags)
30
36
  end if defined?(TimerFD::CLOEXEC)
31
37
 
32
38
  def test_settime
33
- tfd = TimerFD.create(TimerFD::REALTIME)
39
+ tfd = TimerFD.new(TimerFD::REALTIME)
34
40
  assert_equal([0, 0], tfd.settime(TimerFD::ABSTIME, 0, 0.01))
35
41
  sleep 0.01
36
42
  assert_equal 1, tfd.expirations
37
43
  end
44
+
45
+ def test_settime_symbol
46
+ tfd = TimerFD.new(:REALTIME)
47
+ assert_equal([0, 0], tfd.settime(:ABSTIME, 0, 0.01))
48
+ sleep 0.01
49
+ assert_equal 1, tfd.expirations
50
+ end
51
+
52
+ def test_gettime
53
+ tfd = TimerFD.new :REALTIME
54
+ now = Time.now.to_i
55
+ assert_equal([0, 0], tfd.settime(nil, 0, now + 5))
56
+ interval, value = tfd.gettime
57
+ assert_equal 0, interval
58
+ assert_in_delta now + 5, value, 0.01
59
+ end
60
+
61
+ def test_expirations_nonblock
62
+ tfd = TimerFD.new(:MONOTONIC)
63
+ assert_equal([0, 0], tfd.settime(0, 0, 0.01))
64
+ assert_nil tfd.expirations(true)
65
+ sleep 0.01
66
+ assert_equal 1, tfd.expirations
67
+ end
38
68
  end if defined?(SleepyPenguin::TimerFD)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sleepy_penguin
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
5
- prerelease: false
4
+ hash: 15
5
+ prerelease:
6
6
  segments:
7
- - 1
8
- - 4
7
+ - 2
8
+ - 0
9
9
  - 0
10
- version: 1.4.0
10
+ version: 2.0.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - sleepy_penguin hackers
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-04 00:00:00 +00:00
18
+ date: 2011-03-10 00:00:00 +00:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -51,7 +51,7 @@ dependencies:
51
51
  description: |-
52
52
  sleepy_penguin provides access to newer, Linux-only system calls to wait
53
53
  on events from traditionally non-I/O sources. Bindings to the eventfd,
54
- timerfd, and epoll interfaces are provided.
54
+ timerfd, inotify, signalfd and epoll interfaces are provided.
55
55
  email: sleepy.penguin@librelist.com
56
56
  executables: []
57
57
 
@@ -64,9 +64,13 @@ extra_rdoc_files:
64
64
  - NEWS
65
65
  - ChangeLog
66
66
  - lib/sleepy_penguin.rb
67
+ - lib/sleepy_penguin/signalfd/sig_info.rb
68
+ - lib/sleepy_penguin/sp.rb
67
69
  - ext/sleepy_penguin/init.c
68
70
  - ext/sleepy_penguin/epoll.c
69
71
  - ext/sleepy_penguin/eventfd.c
72
+ - ext/sleepy_penguin/inotify.c
73
+ - ext/sleepy_penguin/signalfd.c
70
74
  - ext/sleepy_penguin/timerfd.c
71
75
  files:
72
76
  - .document
@@ -89,13 +93,17 @@ files:
89
93
  - ext/sleepy_penguin/extconf.rb
90
94
  - ext/sleepy_penguin/init.c
91
95
  - ext/sleepy_penguin/inotify.c
92
- - ext/sleepy_penguin/nonblock.h
96
+ - ext/sleepy_penguin/missing_epoll.h
97
+ - ext/sleepy_penguin/missing_inotify.h
98
+ - ext/sleepy_penguin/signalfd.c
93
99
  - ext/sleepy_penguin/sleepy_penguin.h
94
100
  - ext/sleepy_penguin/timerfd.c
101
+ - ext/sleepy_penguin/util.c
95
102
  - ext/sleepy_penguin/value2timespec.h
96
103
  - lib/sleepy_penguin.rb
104
+ - lib/sleepy_penguin/signalfd/sig_info.rb
105
+ - lib/sleepy_penguin/sp.rb
97
106
  - pkg.mk
98
- - script/isolate_for_tests
99
107
  - setup.rb
100
108
  - sleepy_penguin.gemspec
101
109
  - test/test_epoll.rb
@@ -103,6 +111,8 @@ files:
103
111
  - test/test_epoll_optimizations.rb
104
112
  - test/test_eventfd.rb
105
113
  - test/test_inotify.rb
114
+ - test/test_signalfd.rb
115
+ - test/test_signalfd_siginfo.rb
106
116
  - test/test_timerfd.rb
107
117
  has_rdoc: true
108
118
  homepage: http://bogomips.org/sleepy_penguin/
@@ -138,13 +148,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
148
  requirements: []
139
149
 
140
150
  rubyforge_project: rainbows
141
- rubygems_version: 1.3.7
151
+ rubygems_version: 1.6.1
142
152
  signing_key:
143
153
  specification_version: 3
144
154
  summary: Linux I/O events for Ruby
145
155
  test_files:
146
156
  - test/test_epoll_optimizations.rb
157
+ - test/test_signalfd_siginfo.rb
147
158
  - test/test_epoll.rb
159
+ - test/test_signalfd.rb
148
160
  - test/test_inotify.rb
149
161
  - test/test_eventfd.rb
150
162
  - test/test_epoll_gc.rb
@@ -1,19 +0,0 @@
1
- #ifndef SLEEPY_PENGUIN_NONBLOCK_H
2
- #define SLEEPY_PENGUIN_NONBLOCK_H
3
- #include <unistd.h>
4
- #include <fcntl.h>
5
- #include <ruby.h>
6
- static void set_nonblock(int fd)
7
- {
8
- int flags = fcntl(fd, F_GETFL);
9
-
10
- if (flags == -1)
11
- rb_sys_fail("fcntl(F_GETFL)");
12
- if ((flags & O_NONBLOCK) == O_NONBLOCK)
13
- return;
14
- flags = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
15
- if (flags == -1)
16
- rb_sys_fail("fcntl(F_SETFL)");
17
- }
18
-
19
- #endif /* SLEEPY_PENGUIN_NONBLOCK_H */