sleepy_penguin 1.4.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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 */