cool.io 1.2.0-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/.gitignore +26 -0
  2. data/.rspec +3 -0
  3. data/.travis.yml +5 -0
  4. data/CHANGES.md +177 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +20 -0
  7. data/README.md +172 -0
  8. data/Rakefile +81 -0
  9. data/cool.io.gemspec +28 -0
  10. data/examples/dslified_echo_client.rb +34 -0
  11. data/examples/dslified_echo_server.rb +24 -0
  12. data/examples/echo_client.rb +38 -0
  13. data/examples/echo_server.rb +27 -0
  14. data/examples/google.rb +9 -0
  15. data/examples/httpclient.rb +38 -0
  16. data/ext/cool.io/.gitignore +5 -0
  17. data/ext/cool.io/cool.io.h +58 -0
  18. data/ext/cool.io/cool.io_ext.c +25 -0
  19. data/ext/cool.io/ev_wrap.h +8 -0
  20. data/ext/cool.io/extconf.rb +73 -0
  21. data/ext/cool.io/iowatcher.c +189 -0
  22. data/ext/cool.io/libev.c +8 -0
  23. data/ext/cool.io/loop.c +301 -0
  24. data/ext/cool.io/stat_watcher.c +269 -0
  25. data/ext/cool.io/timer_watcher.c +219 -0
  26. data/ext/cool.io/utils.c +122 -0
  27. data/ext/cool.io/watcher.c +264 -0
  28. data/ext/cool.io/watcher.h +71 -0
  29. data/ext/http11_client/.gitignore +5 -0
  30. data/ext/http11_client/LICENSE +31 -0
  31. data/ext/http11_client/ext_help.h +14 -0
  32. data/ext/http11_client/extconf.rb +6 -0
  33. data/ext/http11_client/http11_client.c +300 -0
  34. data/ext/http11_client/http11_parser.c +403 -0
  35. data/ext/http11_client/http11_parser.h +48 -0
  36. data/ext/http11_client/http11_parser.rl +173 -0
  37. data/ext/iobuffer/extconf.rb +9 -0
  38. data/ext/iobuffer/iobuffer.c +765 -0
  39. data/ext/libev/Changes +388 -0
  40. data/ext/libev/LICENSE +36 -0
  41. data/ext/libev/README +58 -0
  42. data/ext/libev/README.embed +3 -0
  43. data/ext/libev/ev.c +4803 -0
  44. data/ext/libev/ev.h +845 -0
  45. data/ext/libev/ev_epoll.c +279 -0
  46. data/ext/libev/ev_kqueue.c +214 -0
  47. data/ext/libev/ev_poll.c +148 -0
  48. data/ext/libev/ev_port.c +185 -0
  49. data/ext/libev/ev_select.c +314 -0
  50. data/ext/libev/ev_vars.h +203 -0
  51. data/ext/libev/ev_win32.c +163 -0
  52. data/ext/libev/ev_wrap.h +200 -0
  53. data/ext/libev/test_libev_win32.c +123 -0
  54. data/lib/.gitignore +2 -0
  55. data/lib/cool.io.rb +32 -0
  56. data/lib/cool.io/async_watcher.rb +43 -0
  57. data/lib/cool.io/custom_require.rb +9 -0
  58. data/lib/cool.io/dns_resolver.rb +225 -0
  59. data/lib/cool.io/dsl.rb +135 -0
  60. data/lib/cool.io/eventmachine.rb +234 -0
  61. data/lib/cool.io/http_client.rb +427 -0
  62. data/lib/cool.io/io.rb +174 -0
  63. data/lib/cool.io/iowatcher.rb +17 -0
  64. data/lib/cool.io/listener.rb +93 -0
  65. data/lib/cool.io/loop.rb +130 -0
  66. data/lib/cool.io/meta.rb +49 -0
  67. data/lib/cool.io/server.rb +74 -0
  68. data/lib/cool.io/socket.rb +230 -0
  69. data/lib/cool.io/timer_watcher.rb +17 -0
  70. data/lib/cool.io/version.rb +5 -0
  71. data/lib/coolio.rb +2 -0
  72. data/spec/async_watcher_spec.rb +57 -0
  73. data/spec/dns_spec.rb +39 -0
  74. data/spec/spec_helper.rb +12 -0
  75. data/spec/stat_watcher_spec.rb +77 -0
  76. data/spec/timer_watcher_spec.rb +55 -0
  77. data/spec/unix_listener_spec.rb +25 -0
  78. data/spec/unix_server_spec.rb +25 -0
  79. metadata +200 -0
data/cool.io.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "cool.io/version"
4
+
5
+ module Cool
6
+ # Allow Coolio module to be referenced as Cool.io
7
+ def self.io; Coolio; end
8
+ end
9
+
10
+ Gem::Specification.new do |s|
11
+ s.name = "cool.io"
12
+ s.version = Coolio::VERSION
13
+ s.authors = ["Tony Arcieri", "Masahiro Nakagawa"]
14
+ s.email = ["tony.arcieri@gmail.com", "repeatedly@gmail.com"]
15
+ s.homepage = "http://coolio.github.com"
16
+ s.summary = "A cool framework for doing high performance I/O in Ruby"
17
+ s.description = "Cool.io provides a high performance event framework for Ruby which uses the libev C library"
18
+ s.extensions = ["ext/cool.io/extconf.rb", "ext/http11_client/extconf.rb", "ext/iobuffer/extconf.rb"]
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
23
+ s.require_paths = ["lib"]
24
+
25
+ s.add_development_dependency "rake-compiler", "~> 0.8.3"
26
+ s.add_development_dependency "rspec", ">= 2.13.0"
27
+ s.add_development_dependency "rdoc", ">= 3.6.0"
28
+ end
@@ -0,0 +1,34 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'rubygems'
4
+ require 'cool.io'
5
+
6
+ ADDR = '127.0.0.1'
7
+ PORT = 4321
8
+
9
+ cool.io.connect ADDR, PORT do
10
+ on_connect do
11
+ puts "Connected to #{remote_host}:#{remote_port}"
12
+ write "bounce this back to me"
13
+ end
14
+
15
+ on_close do
16
+ puts "Disconnected from #{remote_host}:#{remote_port}"
17
+ end
18
+
19
+ on_read do |data|
20
+ puts "Got: #{data}"
21
+ close
22
+ end
23
+
24
+ on_resolve_failed do
25
+ puts "Error: Couldn't resolve #{remote_host}"
26
+ end
27
+
28
+ on_connect_failed do
29
+ puts "Error: Connection refused to #{remote_host}:#{remote_port}"
30
+ end
31
+ end
32
+
33
+ puts "Echo client connecting to #{ADDR}:#{PORT}..."
34
+ cool.io.run
@@ -0,0 +1,24 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'rubygems'
4
+ require 'cool.io'
5
+
6
+ ADDR = '127.0.0.1'
7
+ PORT = 4321
8
+
9
+ cool.io.server ADDR, PORT do
10
+ on_connect do
11
+ puts "#{remote_addr}:#{remote_port} connected"
12
+ end
13
+
14
+ on_close do
15
+ puts "#{remote_addr}:#{remote_port} disconnected"
16
+ end
17
+
18
+ on_read do |data|
19
+ write data
20
+ end
21
+ end
22
+
23
+ puts "Echo server listening on #{ADDR}:#{PORT}"
24
+ cool.io.run
@@ -0,0 +1,38 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'rubygems'
4
+ require 'cool.io'
5
+
6
+ ADDR = '127.0.0.1'
7
+ PORT = 4321
8
+
9
+ class ClientConnection < Cool.io::TCPSocket
10
+ def on_connect
11
+ puts "#{remote_addr}:#{remote_port} connected"
12
+ write "bounce this back to me"
13
+ end
14
+
15
+ def on_close
16
+ puts "#{remote_addr}:#{remote_port} disconnected"
17
+ end
18
+
19
+ def on_read(data)
20
+ print "got #{data}"
21
+ close
22
+ end
23
+
24
+ def on_resolve_failed
25
+ print "DNS resolve failed"
26
+ end
27
+
28
+ def on_connect_failed
29
+ print "connect failed, meaning our connection to their port was rejected"
30
+ end
31
+
32
+ end
33
+
34
+ event_loop = Cool.io::Loop.default
35
+ client = ClientConnection.connect(ADDR, PORT)
36
+ client.attach(event_loop)
37
+ puts "Echo client connecting to #{ADDR}:#{PORT}..."
38
+ event_loop.run
@@ -0,0 +1,27 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'rubygems'
4
+ require 'cool.io'
5
+
6
+ ADDR = '127.0.0.1'
7
+ PORT = 4321
8
+
9
+ class EchoServerConnection < Cool.io::TCPSocket
10
+ def on_connect
11
+ puts "#{remote_addr}:#{remote_port} connected"
12
+ end
13
+
14
+ def on_close
15
+ puts "#{remote_addr}:#{remote_port} disconnected"
16
+ end
17
+
18
+ def on_read(data)
19
+ write data
20
+ end
21
+ end
22
+
23
+ event_loop = Cool.io::Loop.default
24
+ Cool.io::TCPServer.new(ADDR, PORT, EchoServerConnection).attach(event_loop)
25
+
26
+ puts "Echo server listening on #{ADDR}:#{PORT}"
27
+ event_loop.run
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'rubygems'
4
+ require 'cool.io'
5
+
6
+ l = Coolio::Loop.default
7
+ c = Coolio::HttpClient.connect("www.google.com", 80).attach(l)
8
+ c.request('GET', '/search', :query => { :q => 'feces'})
9
+ l.run
@@ -0,0 +1,38 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'rubygems'
4
+ require 'cool.io'
5
+
6
+ class MyHttpClient < Coolio::HttpClient
7
+ def on_connect
8
+ super
9
+ STDERR.puts "Connected to #{remote_host}:#{remote_port}"
10
+ end
11
+
12
+ def on_connect_failed
13
+ super
14
+ STDERR.puts "Connection failed"
15
+ end
16
+
17
+ def on_response_header(header)
18
+ STDERR.puts "Response: #{header.http_version} #{header.status} #{header.http_reason}"
19
+ end
20
+
21
+ def on_body_data(data)
22
+ STDOUT.write data
23
+ STDOUT.flush
24
+ end
25
+
26
+ def on_request_complete
27
+ STDERR.puts "Request complete!"
28
+ end
29
+
30
+ def on_error(reason)
31
+ STDERR.puts "Error: #{reason}"
32
+ end
33
+ end
34
+
35
+ l = Coolio::Loop.default
36
+ c = MyHttpClient.connect("www.google.com", 80).attach(l)
37
+ c.request('GET', '/search', :query => { :q => 'foobar' })
38
+ l.run
@@ -0,0 +1,5 @@
1
+ Makefile
2
+ mkmf.log
3
+ *.o
4
+ *.so
5
+ *.bundle
@@ -0,0 +1,58 @@
1
+ /*
2
+ * Copyright (C) 2007-10 Tony Arcieri
3
+ * You may redistribute this under the terms of the Ruby license.
4
+ * See LICENSE for details
5
+ */
6
+
7
+ #ifndef COOLIO_H
8
+ #define COOLIO_H
9
+
10
+ #include "ruby.h"
11
+ #include "rubyio.h"
12
+
13
+ #ifdef GetReadFile
14
+ #define FPTR_TO_FD(fptr) (fileno(GetReadFile(fptr)))
15
+ #else
16
+
17
+ #if !HAVE_RB_IO_T || (RUBY_VERSION_MAJOR == 1 && RUBY_VERSION_MINOR == 8)
18
+ #define FPTR_TO_FD(fptr) fileno(fptr->f)
19
+ #else
20
+ #define FPTR_TO_FD(fptr) fptr->fd
21
+ #endif
22
+
23
+ #endif
24
+
25
+ struct Coolio_Event
26
+ {
27
+ /* These values are used to extract events from libev callbacks */
28
+ VALUE watcher;
29
+ int revents;
30
+ };
31
+
32
+ struct Coolio_Loop
33
+ {
34
+ struct ev_loop *ev_loop;
35
+
36
+ int running;
37
+ int events_received;
38
+ int eventbuf_size;
39
+ struct Coolio_Event *eventbuf;
40
+ };
41
+
42
+ struct Coolio_Watcher
43
+ {
44
+ union {
45
+ struct ev_io ev_io;
46
+ struct ev_timer ev_timer;
47
+ struct ev_stat ev_stat;
48
+ } event_types;
49
+
50
+ int enabled;
51
+ VALUE loop;
52
+
53
+ void (*dispatch_callback)(VALUE self, int revents);
54
+ };
55
+
56
+ void Coolio_Loop_process_event(VALUE watcher, int revents);
57
+
58
+ #endif
@@ -0,0 +1,25 @@
1
+ /*
2
+ * Copyright (C) 2007-10 Tony Arcieri
3
+ * You may redistribute this under the terms of the Ruby license.
4
+ * See LICENSE for details
5
+ */
6
+
7
+
8
+ #include "ruby.h"
9
+
10
+ #include "ev_wrap.h"
11
+ #include "cool.io.h"
12
+
13
+ static VALUE mCoolio = Qnil;
14
+
15
+ /* Initialize the coolness */
16
+ void Init_cool()
17
+ {
18
+ /* Initializers for other modules */
19
+ Init_coolio_loop();
20
+ Init_coolio_watcher();
21
+ Init_coolio_iowatcher();
22
+ Init_coolio_timer_watcher();
23
+ Init_coolio_stat_watcher();
24
+ Init_coolio_utils();
25
+ }
@@ -0,0 +1,8 @@
1
+ #define EV_STANDALONE /* keeps ev from requiring config.h */
2
+ #ifdef _WIN32
3
+ # define EV_SELECT_IS_WINSOCKET 1 /* configure libev for windows select */
4
+ # define FD_SETSIZE 2048 /* wishful thinking, as msvcrt6 [?] seems to only allow 512 fd's and 256 sockets max */
5
+ #endif
6
+
7
+ #include "../libev/ev.h"
8
+
@@ -0,0 +1,73 @@
1
+ require 'mkmf'
2
+
3
+ libs = []
4
+
5
+ $defs << "-DRUBY_VERSION_CODE=#{RUBY_VERSION.gsub(/\D/, '')}"
6
+
7
+ if have_func('rb_thread_blocking_region')
8
+ $defs << '-DHAVE_RB_THREAD_BLOCKING_REGION'
9
+ end
10
+
11
+ if have_func('rb_thread_alone')
12
+ $defs << '-DHAVE_RB_THREAD_ALONE'
13
+ end
14
+
15
+ if have_func('rb_str_set_len')
16
+ $defs << '-DHAVE_RB_STR_SET_LEN'
17
+ end
18
+
19
+ if have_library('rt', 'clock_gettime')
20
+ libs << "-lrt"
21
+ end
22
+
23
+ if have_header('sys/select.h')
24
+ $defs << '-DEV_USE_SELECT'
25
+ end
26
+
27
+ if have_header('poll.h')
28
+ $defs << '-DEV_USE_POLL'
29
+ end
30
+
31
+ if have_header('sys/epoll.h')
32
+ $defs << '-DEV_USE_EPOLL'
33
+ end
34
+
35
+ if have_header('sys/event.h') and have_header('sys/queue.h')
36
+ $defs << '-DEV_USE_KQUEUE'
37
+ end
38
+
39
+ if have_header('port.h')
40
+ $defs << '-DEV_USE_PORT'
41
+ end
42
+
43
+ if have_header('sys/resource.h')
44
+ $defs << '-DHAVE_SYS_RESOURCE_H'
45
+ end
46
+
47
+ # ncpu detection specifics
48
+ case RUBY_PLATFORM
49
+ when /linux/
50
+ $defs << '-DHAVE_LINUX_PROCFS'
51
+ else
52
+ if have_func('sysctlbyname', ['sys/param.h', 'sys/sysctl.h'])
53
+ $defs << '-DHAVE_SYSCTLBYNAME'
54
+ end
55
+ end
56
+
57
+ $LIBS << ' ' << libs.join(' ')
58
+
59
+ dir_config('cool.io_ext')
60
+ create_makefile('cool.io_ext')
61
+
62
+ # win32 needs to link in "just the right order" for some reason or ioctlsocket will be mapped to an [inverted] ruby specific version. See libev mailing list for (not so helpful discussion--true cause I'm not sure, but this overcomes the symptom)
63
+ if RUBY_PLATFORM =~ /mingw|win32/
64
+ makefile_contents = File.read 'Makefile'
65
+
66
+ # "Init_cool could not be found" when loading cool.io.so.
67
+ # I'm not sure why this is needed. But this line causes "1114 A dynamic link library (DLL) initialization routine failed." So I commented out this line.
68
+ #makefile_contents.gsub! 'DLDFLAGS = ', 'DLDFLAGS = -export-all '
69
+
70
+ makefile_contents.gsub! 'LIBS = $(LIBRUBYARG_SHARED)', 'LIBS = -lws2_32 $(LIBRUBYARG_SHARED)'
71
+ File.open('Makefile', 'w') { |f| f.write makefile_contents }
72
+ end
73
+
@@ -0,0 +1,189 @@
1
+ /*
2
+ * Copyright (C) 2007-10 Tony Arcieri
3
+ * You may redistribute this under the terms of the Ruby license.
4
+ * See LICENSE for details
5
+ */
6
+
7
+ #include "ruby.h"
8
+ #include "rubyio.h"
9
+
10
+ #include "ev_wrap.h"
11
+
12
+ #include "cool.io.h"
13
+ #include "watcher.h"
14
+
15
+ static VALUE mCoolio = Qnil;
16
+ static VALUE cCoolio_Watcher = Qnil;
17
+ static VALUE cCoolio_Loop = Qnil;
18
+ static VALUE cCoolio_IOWatcher = Qnil;
19
+
20
+ static VALUE Coolio_IOWatcher_initialize(int argc, VALUE *argv, VALUE self);
21
+ static VALUE Coolio_IOWatcher_attach(VALUE self, VALUE loop);
22
+ static VALUE Coolio_IOWatcher_detach(VALUE self);
23
+ static VALUE Coolio_IOWatcher_enable(VALUE self);
24
+ static VALUE Coolio_IOWatcher_disable(VALUE self);
25
+ static VALUE Coolio_IOWatcher_on_readable(VALUE self);
26
+ static VALUE Coolio_IOWatcher_on_writable(VALUE self);
27
+
28
+ static void Coolio_IOWatcher_libev_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents);
29
+ static void Coolio_IOWatcher_dispatch_callback(VALUE self, int revents);
30
+
31
+ /*
32
+ * Coolio::IOWatcher monitors Ruby IO objects for readability or writability.
33
+ * This allows your application to block while the kernel is writing out
34
+ * data and fill the read or write buffer whenever there is space available.
35
+ */
36
+ void Init_coolio_iowatcher()
37
+ {
38
+ mCoolio = rb_define_module("Coolio");
39
+ cCoolio_Watcher = rb_define_class_under(mCoolio, "Watcher", rb_cObject);
40
+ cCoolio_IOWatcher = rb_define_class_under(mCoolio, "IOWatcher", cCoolio_Watcher);
41
+ cCoolio_Loop = rb_define_class_under(mCoolio, "Loop", rb_cObject);
42
+
43
+ rb_define_method(cCoolio_IOWatcher, "initialize", Coolio_IOWatcher_initialize, -1);
44
+ rb_define_method(cCoolio_IOWatcher, "attach", Coolio_IOWatcher_attach, 1);
45
+ rb_define_method(cCoolio_IOWatcher, "detach", Coolio_IOWatcher_detach, 0);
46
+ rb_define_method(cCoolio_IOWatcher, "enable", Coolio_IOWatcher_enable, 0);
47
+ rb_define_method(cCoolio_IOWatcher, "disable", Coolio_IOWatcher_disable, 0);
48
+ rb_define_method(cCoolio_IOWatcher, "on_readable", Coolio_IOWatcher_on_readable, 0);
49
+ rb_define_method(cCoolio_IOWatcher, "on_writable", Coolio_IOWatcher_on_writable, 0);
50
+ }
51
+
52
+ /**
53
+ * call-seq:
54
+ * Coolio::IOWatcher.initialize(IO, events = 'r') -> Coolio::IOWatcher
55
+ *
56
+ * Create a new Coolio::IOWatcher for the given IO object and add it to the given Coolio::Loop
57
+ */
58
+ static VALUE Coolio_IOWatcher_initialize(int argc, VALUE *argv, VALUE self)
59
+ {
60
+ VALUE io, flags;
61
+ char *flags_str;
62
+ int events;
63
+ struct Coolio_Watcher *watcher_data;
64
+ #if HAVE_RB_IO_T
65
+ rb_io_t *fptr;
66
+ #else
67
+ OpenFile *fptr;
68
+ #endif
69
+
70
+ rb_scan_args(argc, argv, "11", &io, &flags);
71
+
72
+ if(flags != Qnil)
73
+ flags_str = RSTRING_PTR(rb_String(flags));
74
+ else
75
+ flags_str = "r";
76
+
77
+ if(!strcmp(flags_str, "r"))
78
+ events = EV_READ;
79
+ else if(!strcmp(flags_str, "w"))
80
+ events = EV_WRITE;
81
+ else if(!strcmp(flags_str, "rw"))
82
+ events = EV_READ | EV_WRITE;
83
+ else
84
+ rb_raise(rb_eArgError, "invalid event type: '%s' (must be 'r', 'w', or 'rw')", flags_str);
85
+
86
+ Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
87
+ GetOpenFile(rb_convert_type(io, T_FILE, "IO", "to_io"), fptr);
88
+
89
+ watcher_data->dispatch_callback = Coolio_IOWatcher_dispatch_callback;
90
+ ev_io_init(&watcher_data->event_types.ev_io, Coolio_IOWatcher_libev_callback, FPTR_TO_FD(fptr), events);
91
+ watcher_data->event_types.ev_io.data = (void *)self;
92
+
93
+ return Qnil;
94
+ }
95
+
96
+ /**
97
+ * call-seq:
98
+ * Coolio::IOWatcher.attach(loop) -> Coolio::IOWatcher
99
+ *
100
+ * Attach the IO watcher to the given Coolio::Loop. If the watcher is already attached
101
+ * to a loop, detach it from the old one and attach it to the new one.
102
+ */
103
+ static VALUE Coolio_IOWatcher_attach(VALUE self, VALUE loop)
104
+ {
105
+ Watcher_Attach(io, Coolio_IOWatcher_detach, self, loop);
106
+
107
+ return self;
108
+ }
109
+
110
+ /**
111
+ * call-seq:
112
+ * Coolio::IOWatcher.detach -> Coolio::IOWatcher
113
+ *
114
+ * Detach the IO watcher from its current Coolio::Loop.
115
+ */
116
+ static VALUE Coolio_IOWatcher_detach(VALUE self)
117
+ {
118
+ Watcher_Detach(io, self);
119
+
120
+ return self;
121
+ }
122
+
123
+ /**
124
+ * call-seq:
125
+ * Coolio::IOWatcher.enable -> Coolio::IOWatcher
126
+ *
127
+ * Re-enable an IO watcher which has been temporarily disabled. See the
128
+ * disable method for a more thorough explanation.
129
+ */
130
+ static VALUE Coolio_IOWatcher_enable(VALUE self)
131
+ {
132
+ Watcher_Enable(io, self);
133
+
134
+ return self;
135
+ }
136
+
137
+ /**
138
+ * call-seq:
139
+ * Coolio::IOWatcher.disable -> Coolio::IOWatcher
140
+ *
141
+ * Temporarily disable an IO watcher which is attached to a loop.
142
+ * This is useful if you wish to toggle event monitoring on and off.
143
+ */
144
+ static VALUE Coolio_IOWatcher_disable(VALUE self)
145
+ {
146
+ Watcher_Disable(io, self);
147
+
148
+ return self;
149
+ }
150
+
151
+ /**
152
+ * call-seq:
153
+ * Coolio::IOWatcher#on_readable -> nil
154
+ *
155
+ * Called whenever the IO object associated with the IOWatcher is readable
156
+ */
157
+ static VALUE Coolio_IOWatcher_on_readable(VALUE self)
158
+ {
159
+ return Qnil;
160
+ }
161
+
162
+ /**
163
+ * call-seq:
164
+ * Coolio::IOWatcher#on_writable -> nil
165
+ *
166
+ * Called whenever the IO object associated with the IOWatcher is writable
167
+ */
168
+
169
+ static VALUE Coolio_IOWatcher_on_writable(VALUE self)
170
+ {
171
+ return Qnil;
172
+ }
173
+
174
+ /* libev callback */
175
+ static void Coolio_IOWatcher_libev_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents)
176
+ {
177
+ Coolio_Loop_process_event((VALUE)io->data, revents);
178
+ }
179
+
180
+ /* Coolio::Loop dispatch callback */
181
+ static void Coolio_IOWatcher_dispatch_callback(VALUE self, int revents)
182
+ {
183
+ if(revents & EV_READ)
184
+ rb_funcall(self, rb_intern("on_readable"), 0, 0);
185
+ else if(revents & EV_WRITE)
186
+ rb_funcall(self, rb_intern("on_writable"), 0, 0);
187
+ else
188
+ rb_raise(rb_eRuntimeError, "unknown revents value for ev_io: %d", revents);
189
+ }