io-epoll 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c4f6bb1879b7524f23926e37da7c5fe53dec55b4
4
- data.tar.gz: a0b1c12561b78414aa9f9fb3b567be508daf2685
3
+ metadata.gz: f1d5379f3b1a1f7630975f462c9580f0156d53b0
4
+ data.tar.gz: f9627c3a392a839c64b204aeae939d1fbf8da753
5
5
  SHA512:
6
- metadata.gz: be6db2e498ced13bb8d5219f1d2ab60386cd00b8d3311887ad9dbf13feae7d902a59e8a096103cb16007a4c6944020ba58de827f46691e30316c7db9fa004c65
7
- data.tar.gz: 736de758a7a0a143b51fca8831d5679bac11c66033e40c6d6cfcba14fc5cceefabe1a5a649007c13dfd5a66b884094090b3c4864931b1fe3aaae41ece987b946
6
+ metadata.gz: 10dfbf4366e5c54dbad66a2bf33d822851d9e2481eda47007348b7446c7939433efd0272bb65a918bec2c6c4486b57a9f1a067c045222d84eeb9831852bf1cd4
7
+ data.tar.gz: 0bf8d0e53cfb0bd207ed962341481c30c561301752b8f50e4a7767adef959950cd80f4d55644eddcdd7a09711804ffa6e8c2e8b3c1cb7aa5ac7fced2c23e46f5
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.4
4
+ - 2.2.0
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- io-epoll (0.0.1)
4
+ io-epoll (0.0.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  io-epoll
2
2
  ===
3
3
 
4
+ [![Build Status](https://travis-ci.org/ksss/io-epoll.svg?branch=master)](https://travis-ci.org/ksss/io-epoll)
5
+
4
6
  An experimental binding of epoll(7).
5
7
 
6
8
  **epoll(7)** can use Linux only. (because must be installed sys/epoll.h)
@@ -14,24 +16,32 @@ IO.epoll([io1, io2, io3], Epoll::IN) do |ev|
14
16
  # ev is IO::Epoll::Event object like `struct epoll_event`
15
17
  # it's have data and events properties
16
18
 
17
- # events is event flag bits (Fixnum)
19
+ # IO::Epoll::Event#events is event flag bits (Fixnum)
18
20
  events = ev.events
19
21
 
20
- # data is notificated IO (IO)
22
+ # IO::Epoll::Event#data is notified IO (IO)
21
23
  data = ev.data
22
24
  end
23
25
 
26
+ # or
27
+
28
+ # evlist is Array of IO::Epoll::Event
29
+ # it's just short hand for epoll_create(2) -> epoll_ctl(2) -> epoll_wait(2)
30
+ evlist = IO.epoll([io1, io2, io3], Epoll::IN)
31
+
24
32
  # on other way, you can make instance of IO::Epoll
25
33
 
26
34
  Epoll = IO::Epoll
27
35
 
28
36
  # IO::Epoll.create
29
- # run epoll_create(2)
37
+ # call epoll_create(2)
30
38
  # it's just alias of `new`
39
+ # Epoll object stock a File Descriptor returned by epoll_create(2)
40
+ # return: instance of IO::Epoll
31
41
  epoll = Epoll.create
32
42
 
33
43
  # IO::Epoll#ctl(option, io, flag)
34
- # run epoll_ctl(2)
44
+ # call epoll_ctl(2)
35
45
  # option: you can choice epoll_ctl option in CTL_ADD, CTL_MOD and CTL_DEL.
36
46
  # CTL_ADD: add io list to watching for created epoll fd
37
47
  # CTL_MOD: you can change io events
@@ -39,6 +49,7 @@ epoll = Epoll.create
39
49
  # io: set an IO object for watching.
40
50
  # flag: set flag bits like Epoll::IN|Epoll::OUT|Epoll::ONESHOT etc...
41
51
  # see also man epoll_ctl(2)
52
+ # return: self
42
53
  epoll.ctl(Epoll::CTL_ADD, io, Epoll::IN)
43
54
 
44
55
  # and you can use short way
@@ -47,13 +58,35 @@ epoll.mod(io, Epoll::OUT) # same way to epoll.ctl(Epoll::CTL_MOD, io, Epoll::IN)
47
58
  epoll.del(io) # same way to epoll.ctl(Epoll::CTL_DEL, io)
48
59
 
49
60
  # IO::Epoll#wait(timeout=-1)
50
- # run epoll_wait(2)
61
+ # call epoll_wait(2)
51
62
  # timeout = -1: block until receive event or signals
52
63
  # timeout = 0: return all io's can I/O on non block
53
64
  # timeout > 0: block when timeout pass miri second or receive events or signals
65
+ # return: Array of IO::Epoll::Event
54
66
  evlist = epoll.wait
67
+
68
+ # you can close File Descriptor for epoll when finish to use
69
+ epoll.close #=> nil
70
+
71
+ # and you can check closed
72
+ epoll.closed? #=> true
55
73
  ```
56
74
 
75
+ ## Event flags
76
+
77
+ event flags|ctl|wait|description
78
+ ---|---|---|---
79
+ **IO::Epoll::IN**|o|o|readable
80
+ **IO::Epoll::PRI**|o|o|high priority read
81
+ **IO::Epoll::HUP**|o|o|peer socket was shutdown
82
+ **IO::Epoll::OUT**|o|o|writable
83
+ **IO::Epoll::ET**|o|x|use edge trigger
84
+ **IO::Epoll:ONESHOT**|o|x|auto watching stop when notified(but stay in list)
85
+ **IO::Epoll::ERR**|x|o|raise error
86
+ **IO::Epoll::HUP**|x|o|raise hang up
87
+
88
+ see also **man epoll(7)**
89
+
57
90
  ## Installation
58
91
 
59
92
  Add this line to your application's Gemfile:
data/Rakefile CHANGED
@@ -2,10 +2,11 @@ require "bundler/gem_tasks"
2
2
  require 'rake/extensiontask'
3
3
  require 'rake/testtask'
4
4
 
5
+ task :default => [:compile, :test]
6
+
5
7
  Rake::ExtensionTask.new('epoll') do |ext|
6
8
  ext.name = 'epoll'
7
9
  ext.ext_dir = 'ext/io/epoll'
8
10
  ext.lib_dir = 'lib/io/epoll'
9
11
  end
10
12
  Rake::TestTask.new {|t| t.libs << 'test'}
11
-
data/ext/io/epoll/epoll.c CHANGED
@@ -89,24 +89,26 @@ rb_epoll_ctl(int argc, VALUE *argv, VALUE self)
89
89
  VALUE flag;
90
90
  VALUE io;
91
91
  VALUE events;
92
+ rb_io_t *fptr;
92
93
  int fd;
93
94
 
94
95
  switch (rb_scan_args(argc, argv, "21", &flag, &io, &events)) {
95
96
  case 2:
96
- if (FIX2INT(flag) != EPOLL_CTL_DEL) {
97
+ if (FIX2INT(flag) != EPOLL_CTL_DEL)
97
98
  rb_raise(rb_eArgError, "too few argument for CTL_ADD or CTL_MOD");
98
- }
99
99
  break;
100
100
  case 3:
101
- if (FIX2INT(flag) != EPOLL_CTL_ADD && FIX2INT(flag) != EPOLL_CTL_MOD) {
101
+ if (FIX2INT(flag) != EPOLL_CTL_ADD && FIX2INT(flag) != EPOLL_CTL_MOD)
102
102
  rb_raise(rb_eArgError, "too many argument for CTL_DEL");
103
- }
104
- ev.events = FIX2INT(events);
103
+ if ((FIX2LONG(events) & (EPOLLIN|EPOLLPRI|EPOLLRDHUP|EPOLLOUT|EPOLLET|EPOLLONESHOT)) == 0)
104
+ rb_raise(rb_eIOError, "undefined events");
105
+ ev.events = FIX2LONG(events);
105
106
  ev.data.ptr = (void*)io;
106
107
  break;
107
108
  }
108
109
 
109
- fd = RFILE(io)->fptr->fd;
110
+ GetOpenFile(rb_io_get_io(io), fptr);
111
+ fd = fptr->fd;
110
112
 
111
113
  if (epoll_ctl(ptr->epfd, FIX2INT(flag), fd, &ev) == -1) {
112
114
  char buf[128];
@@ -148,15 +150,18 @@ rb_epoll_wait(int argc, VALUE *argv, VALUE self)
148
150
  {
149
151
  struct Epoll *ptr = get_epoll(self);
150
152
  VALUE ready_evlist;
153
+ VALUE cEvent;
151
154
  VALUE event;
152
155
  struct epoll_event *evlist;
153
156
  int i, ready;
154
157
  int timeout = -1;
155
158
  struct epoll_wait_args data;
156
159
 
157
- if (argc == 1) {
160
+ if (argc == 1)
158
161
  timeout = FIX2INT(argv[0]);
159
- }
162
+ if (ptr->ev_len <= 0)
163
+ rb_raise(rb_eIOError, "empty interest list");
164
+
160
165
  evlist = ruby_xmalloc(ptr->ev_len * sizeof(struct epoll_event));
161
166
 
162
167
  data.ptr = ptr;
@@ -176,10 +181,11 @@ RETRY:
176
181
  }
177
182
 
178
183
  ready_evlist = rb_ary_new_capa(ready);
184
+ cEvent = rb_path2class("IO::Epoll::Event");
179
185
  for (i = 0; i < ready; i++) {
180
- event = rb_obj_alloc(rb_path2class("IO::Epoll::Event"));
186
+ event = rb_obj_alloc(cEvent);
181
187
  RSTRUCT_SET(event, 0, (VALUE) evlist[i].data.ptr);
182
- RSTRUCT_SET(event, 1, INT2FIX(evlist[i].events));
188
+ RSTRUCT_SET(event, 1, LONG2FIX(evlist[i].events));
183
189
  rb_ary_store(ready_evlist, i, event);
184
190
  }
185
191
  ruby_xfree(evlist);
data/io-epoll.gemspec CHANGED
@@ -1,11 +1,11 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "io-epoll"
3
- spec.version = "0.0.1"
3
+ spec.version = "0.0.2"
4
4
  spec.authors = ["ksss"]
5
5
  spec.email = ["co000ri@gmail.com"]
6
6
  spec.summary = %q{An experimental binding of epoll(7)}
7
7
  spec.description = %q{An experimental binding of epoll(7)}
8
- spec.homepage = ""
8
+ spec.homepage = "https://github.com/ksss/io-epoll"
9
9
  spec.license = "MIT"
10
10
 
11
11
  spec.files = `git ls-files`.split($/)
data/lib/io/epoll.rb CHANGED
@@ -27,6 +27,7 @@ class IO
27
27
  end
28
28
 
29
29
  def self.epoll(ios, events)
30
+ ios = ios.to_a
30
31
  open_len = ios.length
31
32
  ep = Epoll.create
32
33
  ios.each do |io|
@@ -43,9 +44,11 @@ class IO
43
44
  end
44
45
  end
45
46
  end
46
- nil
47
+ ep.close
47
48
  else
48
- ep.wait
49
+ evlist = ep.wait
50
+ ep.close
51
+ evlist
49
52
  end
50
53
  end
51
54
  end
data/test/test_epoll.rb CHANGED
@@ -5,32 +5,35 @@ require_relative '../lib/io/epoll'
5
5
  class TestIOEpoll < Test::Unit::TestCase
6
6
  def test_initalize
7
7
  assert_instance_of(IO::Epoll, IO::Epoll.new);
8
+ assert_instance_of(IO::Epoll, IO::Epoll.create);
8
9
  end
9
10
 
10
11
  def test_fileno
11
- assert { 0 < IO::Epoll.new.fileno }
12
+ assert { 0 < IO::Epoll.create.fileno }
12
13
  end
13
14
 
14
15
  def test_ctl
15
- ep = IO::Epoll.new
16
+ ep = IO::Epoll.create
16
17
  io = IO.new(1, 'w')
18
+ assert { ep == ep.ctl(IO::Epoll::CTL_ADD, io , IO::Epoll::OUT) }
17
19
  assert_raise(ArgumentError) { ep.ctl }
18
20
  assert_raise(ArgumentError) { ep.ctl(IO::Epoll::CTL_ADD) }
19
21
  assert_raise(ArgumentError) { ep.ctl(IO::Epoll::CTL_ADD, io) }
20
- assert { ep == ep.ctl(IO::Epoll::CTL_ADD, io , IO::Epoll::OUT) }
21
22
  assert_raise(ArgumentError) { ep.ctl(-1, io) }
23
+ assert_raise(TypeError) { ep.ctl(nil, nil, nil) }
22
24
  end
23
25
 
24
26
  def test_add
25
- ep = IO::Epoll.new
27
+ ep = IO::Epoll.create
26
28
  io = IO.new(1, 'w')
27
- assert { ep == ep.add(io, IO::Epoll::OUT) }
29
+ assert_raise(IOError) { ep.add(io, 0) }
30
+ assert { ep == ep.add(io, IO::Epoll::IN|IO::Epoll::PRI|IO::Epoll::RDHUP|IO::Epoll::ET|IO::Epoll::OUT) }
28
31
  ep.close
29
32
  assert_raise(Errno::EBADF) { ep.add(io, IO::Epoll::OUT) }
30
33
  end
31
34
 
32
35
  def test_mod
33
- ep = IO::Epoll.new
36
+ ep = IO::Epoll.create
34
37
  io = IO.new(1, 'w')
35
38
  assert_raise(Errno::ENOENT) { ep.mod(io, IO::Epoll::IN) }
36
39
  ep == ep.add(io, IO::Epoll::OUT)
@@ -40,7 +43,7 @@ class TestIOEpoll < Test::Unit::TestCase
40
43
  end
41
44
 
42
45
  def test_del
43
- ep = IO::Epoll.new
46
+ ep = IO::Epoll.create
44
47
  io = IO.new(1, 'w')
45
48
  assert_raise(Errno::ENOENT) { ep.del(io) }
46
49
  ep.add(io, IO::Epoll::OUT)
@@ -50,15 +53,16 @@ class TestIOEpoll < Test::Unit::TestCase
50
53
  end
51
54
 
52
55
  def test_wait
53
- ep = IO::Epoll.new
54
- io1 = IO.new(1, 'w')
55
- io2 = IO.new(2, 'w')
56
- ep.add(io1, IO::Epoll::OUT)
57
- assert { [IO::Epoll::Event.new(io1, IO::Epoll::OUT)] == ep.wait }
56
+ ep = IO::Epoll.create
57
+ io = IO.new(1, 'w')
58
+ ep.add(io, IO::Epoll::IN|IO::Epoll::PRI|IO::Epoll::RDHUP|IO::Epoll::ET|IO::Epoll::OUT)
59
+ assert { [IO::Epoll::Event.new(io, IO::Epoll::OUT)] == ep.wait }
60
+ assert_raise(TypeError) { ep.wait(nil) }
61
+ assert_raise(IOError) { IO::Epoll.create.wait }
58
62
  end
59
63
 
60
64
  def test_wait_with_timeout
61
- ep = IO::Epoll.new
65
+ ep = IO::Epoll.create
62
66
  io = IO.new(1, 'w')
63
67
  ep.add(io, IO::Epoll::IN)
64
68
  assert { [] == ep.wait(0) }
@@ -69,7 +73,7 @@ class TestIOEpoll < Test::Unit::TestCase
69
73
  end
70
74
 
71
75
  def test_size
72
- ep = IO::Epoll.new
76
+ ep = IO::Epoll.create
73
77
  io = IO.new(0, 'r')
74
78
  ep.add(io, IO::Epoll::IN)
75
79
  assert { 1 == ep.size }
@@ -78,7 +82,7 @@ class TestIOEpoll < Test::Unit::TestCase
78
82
  end
79
83
 
80
84
  def test_close_closed?
81
- ep = IO::Epoll.new
85
+ ep = IO::Epoll.create
82
86
  assert { false == ep.closed? }
83
87
  assert { nil == ep.close }
84
88
  assert_raise(IOError){ ep.close }
@@ -96,6 +100,9 @@ class TestIOEpoll < Test::Unit::TestCase
96
100
  evs = IO.epoll([r], IO::Epoll::IN)
97
101
  assert { 'ok' == evs[0].data.read }
98
102
  assert { false == evs[0].data.closed? }
103
+ assert_raise(IOError) { IO.epoll(nil, nil) }
104
+ assert_raise(IOError) { IO.epoll([], nil) }
105
+ assert_raise(TypeError) { IO.epoll([nil], nil) }
99
106
  end
100
107
 
101
108
  def test_epoll_with_block
@@ -114,7 +121,7 @@ class TestIOEpoll < Test::Unit::TestCase
114
121
  end
115
122
 
116
123
  def test_thread
117
- ep = IO::Epoll.new
124
+ ep = IO::Epoll.create
118
125
  io = IO.new(1, 'w')
119
126
  ep.add(io, IO::Epoll::OUT)
120
127
  ret = nil
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: io-epoll
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - ksss
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-30 00:00:00.000000000 Z
11
+ date: 2014-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -75,6 +75,7 @@ extensions:
75
75
  extra_rdoc_files: []
76
76
  files:
77
77
  - ".gitignore"
78
+ - ".travis.yml"
78
79
  - Gemfile
79
80
  - Gemfile.lock
80
81
  - LICENSE.txt
@@ -85,7 +86,7 @@ files:
85
86
  - io-epoll.gemspec
86
87
  - lib/io/epoll.rb
87
88
  - test/test_epoll.rb
88
- homepage: ''
89
+ homepage: https://github.com/ksss/io-epoll
89
90
  licenses:
90
91
  - MIT
91
92
  metadata: {}