eventmachine 1.0.0.beta.3 → 1.0.0.beta.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. data/.gitignore +5 -0
  2. data/.yardopts +5 -1
  3. data/{docs/GNU → GNU} +0 -0
  4. data/Gemfile +1 -0
  5. data/{docs/COPYING → LICENSE} +0 -0
  6. data/README.md +109 -0
  7. data/Rakefile +8 -0
  8. data/docs/DocumentationGuidesIndex.md +27 -0
  9. data/docs/GettingStarted.md +521 -0
  10. data/docs/{ChangeLog → old/ChangeLog} +0 -0
  11. data/docs/{DEFERRABLES → old/DEFERRABLES} +0 -0
  12. data/docs/{EPOLL → old/EPOLL} +0 -0
  13. data/docs/{INSTALL → old/INSTALL} +0 -0
  14. data/docs/{KEYBOARD → old/KEYBOARD} +0 -0
  15. data/docs/{LEGAL → old/LEGAL} +0 -0
  16. data/docs/{LIGHTWEIGHT_CONCURRENCY → old/LIGHTWEIGHT_CONCURRENCY} +0 -0
  17. data/docs/{PURE_RUBY → old/PURE_RUBY} +0 -0
  18. data/docs/{RELEASE_NOTES → old/RELEASE_NOTES} +0 -0
  19. data/docs/{SMTP → old/SMTP} +0 -0
  20. data/docs/{SPAWNED_PROCESSES → old/SPAWNED_PROCESSES} +0 -0
  21. data/docs/{TODO → old/TODO} +0 -0
  22. data/eventmachine.gemspec +4 -1
  23. data/examples/guides/getting_started/01_eventmachine_echo_server.rb +18 -0
  24. data/examples/guides/getting_started/02_eventmachine_echo_server_that_recognizes_exit_command.rb +22 -0
  25. data/examples/guides/getting_started/03_simple_chat_server.rb +149 -0
  26. data/examples/guides/getting_started/04_simple_chat_server_step_one.rb +27 -0
  27. data/examples/guides/getting_started/05_simple_chat_server_step_two.rb +43 -0
  28. data/examples/guides/getting_started/06_simple_chat_server_step_three.rb +98 -0
  29. data/examples/guides/getting_started/07_simple_chat_server_step_four.rb +121 -0
  30. data/examples/guides/getting_started/08_simple_chat_server_step_five.rb +141 -0
  31. data/examples/{ex_channel.rb → old/ex_channel.rb} +3 -3
  32. data/examples/{ex_queue.rb → old/ex_queue.rb} +0 -0
  33. data/examples/{ex_tick_loop_array.rb → old/ex_tick_loop_array.rb} +0 -0
  34. data/examples/{ex_tick_loop_counter.rb → old/ex_tick_loop_counter.rb} +0 -0
  35. data/examples/{helper.rb → old/helper.rb} +0 -0
  36. data/ext/cmain.cpp +3 -3
  37. data/ext/ed.cpp +90 -15
  38. data/ext/ed.h +5 -5
  39. data/ext/em.cpp +47 -55
  40. data/ext/em.h +12 -2
  41. data/ext/pipe.cpp +2 -2
  42. data/ext/project.h +1 -1
  43. data/ext/rubymain.cpp +48 -3
  44. data/ext/ssl.cpp +5 -0
  45. data/java/src/com/rubyeventmachine/EmReactor.java +2 -2
  46. data/lib/em/buftok.rb +35 -63
  47. data/lib/em/callback.rb +43 -11
  48. data/lib/em/channel.rb +21 -14
  49. data/lib/em/completion.rb +304 -0
  50. data/lib/em/connection.rb +339 -209
  51. data/lib/em/deferrable.rb +4 -0
  52. data/lib/em/deferrable/pool.rb +2 -0
  53. data/lib/em/file_watch.rb +37 -18
  54. data/lib/em/iterator.rb +42 -42
  55. data/lib/em/pool.rb +146 -0
  56. data/lib/em/process_watch.rb +5 -4
  57. data/lib/em/processes.rb +8 -4
  58. data/lib/em/protocols/httpclient.rb +22 -11
  59. data/lib/em/protocols/httpclient2.rb +15 -5
  60. data/lib/em/protocols/line_protocol.rb +2 -1
  61. data/lib/em/protocols/memcache.rb +17 -9
  62. data/lib/em/protocols/object_protocol.rb +2 -1
  63. data/lib/em/protocols/postgres3.rb +8 -9
  64. data/lib/em/protocols/smtpclient.rb +19 -11
  65. data/lib/em/protocols/smtpserver.rb +1 -1
  66. data/lib/em/protocols/stomp.rb +8 -6
  67. data/lib/em/protocols/tcptest.rb +3 -2
  68. data/lib/em/pure_ruby.rb +212 -208
  69. data/lib/em/queue.rb +22 -13
  70. data/lib/em/resolver.rb +70 -64
  71. data/lib/em/spawnable.rb +6 -3
  72. data/lib/em/streamer.rb +33 -45
  73. data/lib/em/threaded_resource.rb +90 -0
  74. data/lib/em/timers.rb +6 -2
  75. data/lib/em/version.rb +1 -1
  76. data/lib/eventmachine.rb +538 -602
  77. data/lib/jeventmachine.rb +22 -1
  78. data/tasks/package.rake +12 -2
  79. data/tasks/test.rake +1 -0
  80. data/tests/em_test_helper.rb +12 -3
  81. data/tests/test_completion.rb +177 -0
  82. data/tests/test_epoll.rb +2 -2
  83. data/tests/test_httpclient.rb +9 -9
  84. data/tests/test_httpclient2.rb +11 -9
  85. data/tests/test_ltp.rb +2 -10
  86. data/tests/test_pool.rb +128 -0
  87. data/tests/test_processes.rb +20 -2
  88. data/tests/test_queue.rb +8 -0
  89. data/tests/test_resolver.rb +1 -1
  90. data/tests/test_set_sock_opt.rb +37 -0
  91. data/tests/test_shutdown_hooks.rb +23 -0
  92. data/tests/test_threaded_resource.rb +53 -0
  93. data/tests/test_unbind_reason.rb +31 -0
  94. metadata +262 -192
  95. data/README +0 -81
  96. data/tasks/doc.rake +0 -30
@@ -357,7 +357,7 @@ module EventMachine
357
357
 
358
358
  def process_auth_line(line)
359
359
  plain = line.unpack("m").first
360
- discard,user,psw = plain.split("\000")
360
+ _,user,psw = plain.split("\000")
361
361
  if receive_plain_auth user,psw
362
362
  send_data "235 authentication ok\r\n"
363
363
  @state << :auth
@@ -64,12 +64,14 @@ module EventMachine
64
64
  # Body of the message
65
65
  attr_accessor :body
66
66
 
67
- def initialize # :nodoc:
67
+ # @private
68
+ def initialize
68
69
  @header = {}
69
70
  @state = :precommand
70
71
  @content_length = nil
71
72
  end
72
- def consume_line line # :nodoc:
73
+ # @private
74
+ def consume_line line
73
75
  if @state == :precommand
74
76
  unless line =~ /\A\s*\Z/
75
77
  @command = line
@@ -100,8 +102,7 @@ module EventMachine
100
102
  end
101
103
  end
102
104
 
103
- # :stopdoc:
104
-
105
+ # @private
105
106
  def send_frame verb, headers={}, body=""
106
107
  ary = [verb, "\n"]
107
108
  headers.each {|k,v| ary << "#{k}:#{v}\n" }
@@ -113,6 +114,7 @@ module EventMachine
113
114
  send_data ary.join
114
115
  end
115
116
 
117
+ # @private
116
118
  def receive_line line
117
119
  @stomp_initialized || init_message_reader
118
120
  @stomp_message.consume_line(line) {|outcome|
@@ -127,12 +129,14 @@ module EventMachine
127
129
  }
128
130
  end
129
131
 
132
+ # @private
130
133
  def receive_binary_data data
131
134
  @stomp_message.body = data[0..-2]
132
135
  receive_msg(@stomp_message) if respond_to?(:receive_msg)
133
136
  init_message_reader
134
137
  end
135
138
 
139
+ # @private
136
140
  def init_message_reader
137
141
  @stomp_initialized = true
138
142
  set_delimiter "\n"
@@ -140,8 +144,6 @@ module EventMachine
140
144
  @stomp_message = Message.new
141
145
  end
142
146
 
143
- # :startdoc:
144
-
145
147
  # Invoked with an incoming Stomp::Message received from the STOMP server
146
148
  def receive_msg msg
147
149
  # stub, overwrite this in your handler
@@ -27,7 +27,8 @@
27
27
  module EventMachine
28
28
  module Protocols
29
29
 
30
- class TcpConnectTester < Connection # :nodoc:
30
+ # @private
31
+ class TcpConnectTester < Connection
31
32
  include EventMachine::Deferrable
32
33
 
33
34
  def self.test( host, port )
@@ -50,4 +51,4 @@ module EventMachine
50
51
  end
51
52
 
52
53
  end
53
- end
54
+ end
@@ -3,7 +3,7 @@
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
5
5
  # Date:: 8 Apr 2006
6
- #
6
+ #
7
7
  # See EventMachine and EventMachine::Connection for documentation and
8
8
  # usage examples.
9
9
  #
@@ -11,17 +11,17 @@
11
11
  #
12
12
  # Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
13
13
  # Gmail: blackhedd
14
- #
14
+ #
15
15
  # This program is free software; you can redistribute it and/or modify
16
16
  # it under the terms of either: 1) the GNU General Public License
17
17
  # as published by the Free Software Foundation; either version 2 of the
18
18
  # License, or (at your option) any later version; or 2) Ruby's License.
19
- #
19
+ #
20
20
  # See the file COPYING for complete licensing information.
21
21
  #
22
22
  #-------------------------------------------------------------------
23
23
  #
24
- #
24
+ #
25
25
 
26
26
  # TODO List:
27
27
  # TCP-connects currently assume non-blocking connect is available- need to
@@ -34,320 +34,330 @@ require 'socket'
34
34
  require 'fcntl'
35
35
  require 'set'
36
36
 
37
- module EventMachine #:nodoc: all
37
+ # @private
38
+ module EventMachine
38
39
  class << self
39
40
  # This is mostly useful for automated tests.
40
41
  # Return a distinctive symbol so the caller knows whether he's dealing
41
42
  # with an extension or with a pure-Ruby library.
43
+ # @private
42
44
  def library_type
43
45
  :pure_ruby
44
46
  end
45
47
 
46
- # #initialize_event_machine
48
+ # @private
47
49
  def initialize_event_machine
48
50
  Reactor.instance.initialize_for_run
49
51
  end
50
52
 
51
- # #add_oneshot_timer
52
- #--
53
53
  # Changed 04Oct06: intervals from the caller are now in milliseconds, but our native-ruby
54
54
  # processor still wants them in seconds.
55
+ # @private
55
56
  def add_oneshot_timer interval
56
57
  Reactor.instance.install_oneshot_timer(interval / 1000)
57
58
  end
58
59
 
59
- # run_machine
60
+ # @private
60
61
  def run_machine
61
62
  Reactor.instance.run
62
63
  end
63
64
 
64
- # release_machine. Probably a no-op.
65
+ # @private
65
66
  def release_machine
66
67
  end
67
68
 
68
- # #stop
69
+ # @private
69
70
  def stop
70
71
  Reactor.instance.stop
71
72
  end
72
73
 
73
- # #connect_server. Return a connection descriptor to the caller.
74
- # TODO, what do we return here if we can't connect?
74
+ # @private
75
75
  def connect_server host, port
76
76
  bind_connect_server nil, nil, host, port
77
77
  end
78
78
 
79
+ # @private
79
80
  def bind_connect_server bind_addr, bind_port, host, port
80
81
  EvmaTCPClient.connect(bind_addr, bind_port, host, port).uuid
81
82
  end
82
83
 
83
- # #send_data
84
+ # @private
84
85
  def send_data target, data, datalength
85
86
  selectable = Reactor.instance.get_selectable( target ) or raise "unknown send_data target"
86
87
  selectable.send_data data
87
88
  end
88
89
 
89
- # #close_connection
90
+
90
91
  # The extension version does NOT raise any kind of an error if an attempt is made
91
92
  # to close a non-existent connection. Not sure whether we should. For now, we'll
92
93
  # raise an error here in that case.
94
+ # @private
93
95
  def close_connection target, after_writing
94
96
  selectable = Reactor.instance.get_selectable( target ) or raise "unknown close_connection target"
95
97
  selectable.schedule_close after_writing
96
98
  end
97
99
 
98
- # #start_tcp_server
100
+ # @private
99
101
  def start_tcp_server host, port
100
102
  (s = EvmaTCPServer.start_server host, port) or raise "no acceptor"
101
103
  s.uuid
102
104
  end
103
105
 
104
- # #stop_tcp_server
106
+ # @private
105
107
  def stop_tcp_server sig
106
108
  s = Reactor.instance.get_selectable(sig)
107
109
  s.schedule_close
108
110
  end
109
111
 
110
- # #start_unix_server
112
+ # @private
111
113
  def start_unix_server chain
112
114
  (s = EvmaUNIXServer.start_server chain) or raise "no acceptor"
113
115
  s.uuid
114
116
  end
115
117
 
116
- # #connect_unix_server
118
+ # @private
117
119
  def connect_unix_server chain
118
120
  EvmaUNIXClient.connect(chain).uuid
119
121
  end
120
122
 
121
- # #signal_loopbreak
123
+ # @private
122
124
  def signal_loopbreak
123
125
  Reactor.instance.signal_loopbreak
124
126
  end
125
127
 
126
- # #get_peername
128
+ # @private
127
129
  def get_peername sig
128
130
  selectable = Reactor.instance.get_selectable( sig ) or raise "unknown get_peername target"
129
131
  selectable.get_peername
130
132
  end
131
133
 
132
- # #open_udp_socket
134
+ # @private
133
135
  def open_udp_socket host, port
134
136
  EvmaUDPSocket.create(host, port).uuid
135
137
  end
136
138
 
137
- # #send_datagram. This is currently only for UDP!
139
+ # This is currently only for UDP!
138
140
  # We need to make it work with unix-domain sockets as well.
141
+ # @private
139
142
  def send_datagram target, data, datalength, host, port
140
143
  selectable = Reactor.instance.get_selectable( target ) or raise "unknown send_data target"
141
144
  selectable.send_datagram data, Socket::pack_sockaddr_in(port, host)
142
145
  end
143
146
 
144
147
 
145
- # #set_timer_quantum in milliseconds. The underlying Reactor function wants a (possibly
148
+ # Sets reactor quantum in milliseconds. The underlying Reactor function wants a (possibly
146
149
  # fractional) number of seconds.
150
+ # @private
147
151
  def set_timer_quantum interval
148
152
  Reactor.instance.set_timer_quantum(( 1.0 * interval) / 1000.0)
149
153
  end
150
154
 
151
- # #epoll is a harmless no-op in the pure-Ruby implementation. This is intended to ensure
155
+ # This method is a harmless no-op in the pure-Ruby implementation. This is intended to ensure
152
156
  # that user code behaves properly across different EM implementations.
157
+ # @private
153
158
  def epoll
154
159
  end
155
160
 
156
- # #ssl? is not implemented for pure-Ruby implementation
161
+ # This method is not implemented for pure-Ruby implementation
162
+ # @private
157
163
  def ssl?
158
164
  false
159
165
  end
160
166
 
161
- # #set_rlimit_nofile is a no-op in the pure-Ruby implementation. We simply return Ruby's built-in
167
+ # This method is a no-op in the pure-Ruby implementation. We simply return Ruby's built-in
162
168
  # per-process file-descriptor limit.
169
+ # @private
163
170
  def set_rlimit_nofile n
164
171
  1024
165
172
  end
166
173
 
167
- # #set_max_timer_count is a harmless no-op in pure Ruby, which doesn't have a built-in limit
174
+ # This method is a harmless no-op in pure Ruby, which doesn't have a built-in limit
168
175
  # on the number of available timers.
176
+ # @private
169
177
  def set_max_timer_count n
170
178
  end
171
179
 
172
- # #send_file_data
180
+ # @private
181
+ def get_sock_opt signature, level, optname
182
+ selectable = Reactor.instance.get_selectable( signature ) or raise "unknown get_peername target"
183
+ selectable.getsockopt level, optname
184
+ end
185
+
186
+ # @private
187
+ def set_sock_opt signature, level, optname, optval
188
+ selectable = Reactor.instance.get_selectable( signature ) or raise "unknown get_peername target"
189
+ selectable.setsockopt level, optname, optval
190
+ end
191
+
192
+ # @private
173
193
  def send_file_data sig, filename
174
194
  sz = File.size(filename)
175
195
  raise "file too large" if sz > 32*1024
176
196
  data =
177
- begin
178
- File.read filename
179
- rescue
180
- ""
181
- end
197
+ begin
198
+ File.read filename
199
+ rescue
200
+ ""
201
+ end
182
202
  send_data sig, data, data.length
183
203
  end
184
204
 
185
- # #get_outbound_data_size
186
- #
205
+ # @private
187
206
  def get_outbound_data_size sig
188
207
  r = Reactor.instance.get_selectable( sig ) or raise "unknown get_outbound_data_size target"
189
208
  r.get_outbound_data_size
190
209
  end
191
210
 
192
- # #read_keyboard
193
- #
211
+ # @private
194
212
  def read_keyboard
195
213
  EvmaKeyboard.open.uuid
196
214
  end
197
215
 
198
- # #set_comm_inactivity_timeout
199
- #
216
+ # @private
200
217
  def set_comm_inactivity_timeout sig, tm
201
218
  r = Reactor.instance.get_selectable( sig ) or raise "unknown set_comm_inactivity_timeout target"
202
219
  r.set_inactivity_timeout tm
203
220
  end
204
221
  end
205
-
206
222
  end
207
223
 
208
224
 
209
- #-----------------------------------------------------------------
210
-
211
- module EventMachine #:nodoc: all
212
-
225
+ module EventMachine
226
+ # @private
213
227
  class Error < Exception; end
214
-
215
228
  end
216
229
 
217
- #-----------------------------------------------------------------
218
-
219
- module EventMachine #:nodoc: all
230
+ module EventMachine
231
+ # @private
220
232
  class Connection
233
+ # @private
221
234
  def get_outbound_data_size
222
235
  EventMachine::get_outbound_data_size @signature
223
236
  end
224
237
  end
225
238
  end
226
239
 
227
- #-----------------------------------------------------------------
228
-
229
- module EventMachine #:nodoc: all
240
+ module EventMachine
230
241
 
231
242
  # Factored out so we can substitute other implementations
232
243
  # here if desired, such as the one in ActiveRBAC.
244
+ # @private
233
245
  module UuidGenerator
234
-
235
246
  def self.generate
236
247
  @ix ||= 0
237
248
  @ix += 1
238
249
  end
239
-
240
250
  end
241
-
242
251
  end
243
252
 
244
- #-----------------------------------------------------------------
245
-
246
- module EventMachine #:nodoc: all
247
253
 
254
+ module EventMachine
255
+ # @private
248
256
  TimerFired = 100
257
+ # @private
249
258
  ConnectionData = 101
259
+ # @private
250
260
  ConnectionUnbound = 102
261
+ # @private
251
262
  ConnectionAccepted = 103
263
+ # @private
252
264
  ConnectionCompleted = 104
265
+ # @private
253
266
  LoopbreakSignalled = 105
254
-
255
267
  end
256
268
 
257
- #-----------------------------------------------------------------
269
+ module EventMachine
270
+ # @private
271
+ class Reactor
272
+ include Singleton
258
273
 
259
- module EventMachine #:nodoc: all
260
- class Reactor
261
- include Singleton
274
+ HeartbeatInterval = 2
262
275
 
263
- HeartbeatInterval = 2
276
+ attr_reader :current_loop_time
264
277
 
265
- attr_reader :current_loop_time
278
+ def initialize
279
+ initialize_for_run
280
+ end
266
281
 
267
- def initialize
268
- initialize_for_run
269
- end
282
+ def install_oneshot_timer interval
283
+ uuid = UuidGenerator::generate
284
+ #@timers << [Time.now + interval, uuid]
285
+ #@timers.sort! {|a,b| a.first <=> b.first}
286
+ @timers.add([Time.now + interval, uuid])
287
+ uuid
288
+ end
270
289
 
271
- #--
272
- # Replaced original implementation 05Dec07, was way too slow because of the sort.
273
- def install_oneshot_timer interval
274
- uuid = UuidGenerator::generate
275
- #@timers << [Time.now + interval, uuid]
276
- #@timers.sort! {|a,b| a.first <=> b.first}
277
- @timers.add([Time.now + interval, uuid])
278
- uuid
279
- end
290
+ # Called before run, this is a good place to clear out arrays
291
+ # with cruft that may be left over from a previous run.
292
+ # @private
293
+ def initialize_for_run
294
+ @running = false
295
+ @stop_scheduled = false
296
+ @selectables ||= {}; @selectables.clear
297
+ @timers = SortedSet.new # []
298
+ set_timer_quantum(0.1)
299
+ @current_loop_time = Time.now
300
+ @next_heartbeat = @current_loop_time + HeartbeatInterval
301
+ end
280
302
 
281
- # Called before run, this is a good place to clear out arrays
282
- # with cruft that may be left over from a previous run.
283
- def initialize_for_run
284
- @running = false
285
- @stop_scheduled = false
286
- @selectables ||= {}; @selectables.clear
287
- @timers = SortedSet.new # []
288
- set_timer_quantum(0.1)
289
- @current_loop_time = Time.now
290
- @next_heartbeat = @current_loop_time + HeartbeatInterval
291
- end
303
+ def add_selectable io
304
+ @selectables[io.uuid] = io
305
+ end
292
306
 
293
- def add_selectable io
294
- @selectables[io.uuid] = io
295
- end
307
+ def get_selectable uuid
308
+ @selectables[uuid]
309
+ end
296
310
 
297
- def get_selectable uuid
298
- @selectables[uuid]
299
- end
311
+ def run
312
+ raise Error.new( "already running" ) if @running
313
+ @running = true
300
314
 
301
- def run
302
- raise Error.new( "already running" ) if @running
303
- @running = true
315
+ begin
316
+ open_loopbreaker
304
317
 
305
- begin
306
- open_loopbreaker
318
+ loop {
319
+ @current_loop_time = Time.now
307
320
 
308
- loop {
309
- @current_loop_time = Time.now
321
+ break if @stop_scheduled
322
+ run_timers
323
+ break if @stop_scheduled
324
+ crank_selectables
325
+ break if @stop_scheduled
326
+ run_heartbeats
327
+ }
328
+ ensure
329
+ close_loopbreaker
330
+ @selectables.each {|k, io| io.close}
331
+ @selectables.clear
310
332
 
311
- break if @stop_scheduled
312
- run_timers
313
- break if @stop_scheduled
314
- crank_selectables
315
- break if @stop_scheduled
316
- run_heartbeats
317
- }
318
- ensure
319
- close_loopbreaker
320
- @selectables.each {|k, io| io.close}
321
- @selectables.clear
333
+ @running = false
334
+ end
322
335
 
323
- @running = false
324
336
  end
325
337
 
326
- end
338
+ def run_timers
339
+ @timers.each {|t|
340
+ if t.first <= @current_loop_time
341
+ @timers.delete t
342
+ EventMachine::event_callback "", TimerFired, t.last
343
+ else
344
+ break
345
+ end
346
+ }
347
+ #while @timers.length > 0 and @timers.first.first <= now
348
+ # t = @timers.shift
349
+ # EventMachine::event_callback "", TimerFired, t.last
350
+ #end
351
+ end
327
352
 
328
- def run_timers
329
- @timers.each {|t|
330
- if t.first <= @current_loop_time
331
- @timers.delete t
332
- EventMachine::event_callback "", TimerFired, t.last
333
- else
334
- break
353
+ def run_heartbeats
354
+ if @next_heartbeat <= @current_loop_time
355
+ @next_heartbeat = @current_loop_time + HeartbeatInterval
356
+ @selectables.each {|k,io| io.heartbeat}
335
357
  end
336
- }
337
- #while @timers.length > 0 and @timers.first.first <= now
338
- # t = @timers.shift
339
- # EventMachine::event_callback "", TimerFired, t.last
340
- #end
341
- end
342
-
343
- def run_heartbeats
344
- if @next_heartbeat <= @current_loop_time
345
- @next_heartbeat = @current_loop_time + HeartbeatInterval
346
- @selectables.each {|k,io| io.heartbeat}
347
358
  end
348
- end
349
359
 
350
- def crank_selectables
360
+ def crank_selectables
351
361
  #$stderr.write 'R'
352
362
 
353
363
  readers = @selectables.values.select {|io| io.select_for_reading?}
@@ -364,57 +374,55 @@ class Reactor
364
374
  true
365
375
  end
366
376
  }
367
- end
377
+ end
368
378
 
369
- # #stop
370
- def stop
371
- raise Error.new( "not running") unless @running
372
- @stop_scheduled = true
373
- end
379
+ # #stop
380
+ def stop
381
+ raise Error.new( "not running") unless @running
382
+ @stop_scheduled = true
383
+ end
384
+
385
+ def open_loopbreaker
386
+ # Can't use an IO.pipe because they can't be set nonselectable in Windows.
387
+ # Pick a random localhost UDP port.
388
+ #@loopbreak_writer.close if @loopbreak_writer
389
+ #rd,@loopbreak_writer = IO.pipe
390
+ @loopbreak_reader = UDPSocket.new
391
+ @loopbreak_writer = UDPSocket.new
392
+ bound = false
393
+ 100.times {
394
+ @loopbreak_port = rand(10000) + 40000
395
+ begin
396
+ @loopbreak_reader.bind "localhost", @loopbreak_port
397
+ bound = true
398
+ break
399
+ rescue
400
+ end
401
+ }
402
+ raise "Unable to bind Loopbreaker" unless bound
403
+ LoopbreakReader.new(@loopbreak_reader)
404
+ end
374
405
 
375
- def open_loopbreaker
376
- # Can't use an IO.pipe because they can't be set nonselectable in Windows.
377
- # Pick a random localhost UDP port.
378
- #@loopbreak_writer.close if @loopbreak_writer
379
- #rd,@loopbreak_writer = IO.pipe
380
- @loopbreak_reader = UDPSocket.new
381
- @loopbreak_writer = UDPSocket.new
382
- bound = false
383
- 100.times {
384
- @loopbreak_port = rand(10000) + 40000
385
- begin
386
- @loopbreak_reader.bind "localhost", @loopbreak_port
387
- bound = true
388
- break
389
- rescue
390
- end
391
- }
392
- raise "Unable to bind Loopbreaker" unless bound
393
- LoopbreakReader.new(@loopbreak_reader)
394
- end
406
+ def close_loopbreaker
407
+ @loopbreak_writer.close
408
+ @loopbreak_writer = nil
409
+ end
395
410
 
396
- def close_loopbreaker
397
- @loopbreak_writer.close
398
- @loopbreak_writer = nil
399
- end
411
+ def signal_loopbreak
412
+ #@loopbreak_writer.write '+' if @loopbreak_writer
413
+ @loopbreak_writer.send('+',0,"localhost",@loopbreak_port) if @loopbreak_writer
414
+ end
400
415
 
401
- def signal_loopbreak
402
- #@loopbreak_writer.write '+' if @loopbreak_writer
403
- @loopbreak_writer.send('+',0,"localhost",@loopbreak_port) if @loopbreak_writer
404
- end
416
+ def set_timer_quantum interval_in_seconds
417
+ @timer_quantum = interval_in_seconds
418
+ end
405
419
 
406
- def set_timer_quantum interval_in_seconds
407
- @timer_quantum = interval_in_seconds
408
420
  end
409
421
 
410
422
  end
411
423
 
412
- end
413
-
414
-
415
- #--------------------------------------------------------------
416
-
417
- class IO #:nodoc: all
424
+ # @private
425
+ class IO
418
426
  extend Forwardable
419
427
  def_delegator :@my_selectable, :close_scheduled?
420
428
  def_delegator :@my_selectable, :select_for_reading?
@@ -431,9 +439,8 @@ class IO #:nodoc: all
431
439
  def_delegator :@my_selectable, :heartbeat
432
440
  end
433
441
 
434
- #--------------------------------------------------------------
435
-
436
- module EventMachine #:nodoc: all
442
+ module EventMachine
443
+ # @private
437
444
  class Selectable
438
445
 
439
446
  attr_reader :io, :uuid
@@ -453,7 +460,7 @@ module EventMachine #:nodoc: all
453
460
  s = Socket.for_fd(@io.fileno)
454
461
  s.fcntl( Fcntl::F_SETFL, Fcntl::O_NONBLOCK )
455
462
  rescue Errno::EINVAL, Errno::EBADF
456
- STDERR.puts "Serious error: unable to set descriptor non-blocking"
463
+ warn "Serious error: unable to set descriptor non-blocking"
457
464
  end
458
465
  end
459
466
  # TODO, should set CLOEXEC on Unix?
@@ -491,11 +498,8 @@ module EventMachine #:nodoc: all
491
498
 
492
499
  end
493
500
 
494
- #--------------------------------------------------------------
495
-
496
-
497
- module EventMachine #:nodoc: all
498
-
501
+ module EventMachine
502
+ # @private
499
503
  class StreamObject < Selectable
500
504
  def initialize io
501
505
  super io
@@ -571,10 +575,10 @@ module EventMachine #:nodoc: all
571
575
  begin
572
576
  data = data.to_s
573
577
  w = if io.respond_to?(:write_nonblock)
574
- io.write_nonblock data
575
- else
576
- io.syswrite data
577
- end
578
+ io.write_nonblock data
579
+ else
580
+ io.syswrite data
581
+ end
578
582
 
579
583
  if w < data.length
580
584
  @outbound_q.unshift data[w..-1]
@@ -636,7 +640,8 @@ end
636
640
 
637
641
 
638
642
 
639
- module EventMachine #:nodoc: all
643
+ module EventMachine
644
+ # @private
640
645
  class EvmaTCPClient < StreamObject
641
646
 
642
647
  def self.connect bind_addr, bind_port, host, port
@@ -683,11 +688,10 @@ module EventMachine #:nodoc: all
683
688
  end
684
689
  end
685
690
 
686
- #--------------------------------------------------------------
687
-
688
691
 
689
692
 
690
- module EventMachine #:nodoc: all
693
+ module EventMachine
694
+ # @private
691
695
  class EvmaKeyboard < StreamObject
692
696
 
693
697
  def self.open
@@ -713,11 +717,9 @@ module EventMachine #:nodoc: all
713
717
  end
714
718
 
715
719
 
716
- #--------------------------------------------------------------
717
-
718
-
719
720
 
720
- module EventMachine #:nodoc: all
721
+ module EventMachine
722
+ # @private
721
723
  class EvmaUNIXClient < StreamObject
722
724
 
723
725
  def self.connect chain
@@ -765,7 +767,8 @@ end
765
767
 
766
768
  #--------------------------------------------------------------
767
769
 
768
- module EventMachine #:nodoc: all
770
+ module EventMachine
771
+ # @private
769
772
  class EvmaTCPServer < Selectable
770
773
 
771
774
  # TODO, refactor and unify with EvmaUNIXServer.
@@ -820,7 +823,8 @@ end
820
823
 
821
824
  #--------------------------------------------------------------
822
825
 
823
- module EventMachine #:nodoc: all
826
+ module EventMachine
827
+ # @private
824
828
  class EvmaUNIXServer < Selectable
825
829
 
826
830
  # TODO, refactor and unify with EvmaTCPServer.
@@ -876,7 +880,8 @@ end
876
880
 
877
881
  #--------------------------------------------------------------
878
882
 
879
- module EventMachine #:nodoc: all
883
+ module EventMachine
884
+ # @private
880
885
  class LoopbreakReader < Selectable
881
886
 
882
887
  def select_for_reading?
@@ -884,18 +889,18 @@ module EventMachine #:nodoc: all
884
889
  end
885
890
 
886
891
  def eventable_read
887
- io.sysread(128)
888
- EventMachine::event_callback "", LoopbreakSignalled, ""
892
+ io.sysread(128)
893
+ EventMachine::event_callback "", LoopbreakSignalled, ""
889
894
  end
890
895
 
891
896
  end
892
897
  end
893
898
 
894
- #--------------------------------------------------------------
895
-
896
899
 
897
- module EventMachine #:nodoc: all
898
900
 
901
+ # @private
902
+ module EventMachine
903
+ # @private
899
904
  class DatagramObject < Selectable
900
905
  def initialize io
901
906
  super io
@@ -939,9 +944,8 @@ module EventMachine #:nodoc: all
939
944
  end
940
945
 
941
946
 
942
- #--------------------------------------------------------------
943
-
944
- module EventMachine #:nodoc: all
947
+ module EventMachine
948
+ # @private
945
949
  class EvmaUDPSocket < DatagramObject
946
950
 
947
951
  class << self