eventmachine 0.10.0 → 0.12.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.
Files changed (89) hide show
  1. data/DEFERRABLES +1 -1
  2. data/LIGHTWEIGHT_CONCURRENCY +1 -1
  3. data/PURE_RUBY +1 -1
  4. data/README +1 -1
  5. data/RELEASE_NOTES +1 -1
  6. data/SMTP +1 -1
  7. data/SPAWNED_PROCESSES +1 -1
  8. data/TODO +1 -1
  9. data/ext/binder.cpp +1 -1
  10. data/ext/binder.h +1 -1
  11. data/ext/cmain.cpp +29 -1
  12. data/ext/cplusplus.cpp +1 -1
  13. data/ext/ed.cpp +79 -1
  14. data/ext/ed.h +6 -1
  15. data/ext/em.cpp +343 -27
  16. data/ext/em.h +25 -1
  17. data/ext/emwin.cpp +1 -1
  18. data/ext/emwin.h +1 -1
  19. data/ext/epoll.cpp +1 -1
  20. data/ext/epoll.h +1 -1
  21. data/ext/eventmachine.h +3 -1
  22. data/ext/eventmachine_cpp.h +1 -1
  23. data/ext/extconf.rb +31 -1
  24. data/ext/files.cpp +1 -1
  25. data/ext/files.h +1 -1
  26. data/ext/kb.cpp +4 -1
  27. data/ext/page.cpp +1 -1
  28. data/ext/page.h +1 -1
  29. data/ext/pipe.cpp +4 -1
  30. data/ext/project.h +8 -2
  31. data/ext/rubymain.cpp +73 -2
  32. data/ext/sigs.cpp +1 -1
  33. data/ext/sigs.h +1 -1
  34. data/ext/ssl.cpp +4 -1
  35. data/ext/ssl.h +1 -1
  36. data/lib/em/deferrable.rb +1 -1
  37. data/lib/em/eventable.rb +1 -1
  38. data/lib/em/future.rb +1 -1
  39. data/lib/em/messages.rb +1 -1
  40. data/lib/em/processes.rb +68 -0
  41. data/lib/em/spawnable.rb +1 -1
  42. data/lib/em/streamer.rb +1 -1
  43. data/lib/eventmachine.rb +113 -66
  44. data/lib/eventmachine_version.rb +2 -2
  45. data/lib/evma.rb +1 -1
  46. data/lib/evma/callback.rb +1 -1
  47. data/lib/evma/container.rb +1 -1
  48. data/lib/evma/factory.rb +1 -1
  49. data/lib/evma/protocol.rb +1 -1
  50. data/lib/evma/reactor.rb +1 -1
  51. data/lib/jeventmachine.rb +1 -1
  52. data/lib/pr_eventmachine.rb +35 -8
  53. data/lib/protocols/header_and_content.rb +1 -1
  54. data/lib/protocols/httpcli2.rb +1 -1
  55. data/lib/protocols/httpclient.rb +1 -1
  56. data/lib/protocols/line_and_text.rb +1 -1
  57. data/lib/protocols/linetext2.rb +1 -1
  58. data/lib/protocols/saslauth.rb +59 -1
  59. data/lib/protocols/smtpclient.rb +4 -3
  60. data/lib/protocols/smtpserver.rb +3 -3
  61. data/lib/protocols/stomp.rb +1 -1
  62. data/lib/protocols/tcptest.rb +1 -1
  63. data/tests/test_basic.rb +2 -1
  64. data/tests/test_defer.rb +63 -0
  65. data/tests/test_epoll.rb +10 -5
  66. data/tests/test_errors.rb +13 -3
  67. data/tests/test_eventables.rb +1 -1
  68. data/tests/test_exc.rb +2 -1
  69. data/tests/test_futures.rb +2 -1
  70. data/tests/test_hc.rb +26 -2
  71. data/tests/test_httpclient.rb +2 -1
  72. data/tests/test_httpclient2.rb +2 -1
  73. data/tests/test_kb.rb +2 -1
  74. data/tests/test_ltp.rb +3 -1
  75. data/tests/test_ltp2.rb +2 -1
  76. data/tests/test_next_tick.rb +2 -1
  77. data/tests/test_processes.rb +56 -0
  78. data/tests/test_pure.rb +2 -1
  79. data/tests/test_running.rb +2 -1
  80. data/tests/test_sasl.rb +73 -0
  81. data/tests/test_send_file.rb +3 -1
  82. data/tests/test_servers.rb +4 -1
  83. data/tests/test_smtpclient.rb +2 -1
  84. data/tests/test_smtpserver.rb +3 -2
  85. data/tests/test_spawn.rb +2 -1
  86. data/tests/test_timers.rb +2 -2
  87. data/tests/test_ud.rb +2 -1
  88. data/tests/testem.rb +1 -1
  89. metadata +115 -104
data/lib/jeventmachine.rb CHANGED
@@ -1,4 +1,4 @@
1
- # $Id: jeventmachine.rb 451 2007-07-21 13:34:28Z blackhedd $
1
+ # $Id: jeventmachine.rb 668 2008-01-04 23:00:34Z blackhedd $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -1,4 +1,4 @@
1
- # $Id: pr_eventmachine.rb 604 2007-12-06 12:31:39Z blackhedd $
1
+ # $Id: pr_eventmachine.rb 668 2008-01-04 23:00:34Z blackhedd $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -374,9 +374,24 @@ class Reactor
374
374
  end
375
375
 
376
376
  def open_loopbreaker
377
- @loopbreak_writer.close if @loopbreak_writer
378
- rd,@loopbreak_writer = IO.pipe
379
- LoopbreakReader.new rd
377
+ # Can't use an IO.pipe because they can't be set nonselectable in Windows.
378
+ # Pick a random localhost UDP port.
379
+ #@loopbreak_writer.close if @loopbreak_writer
380
+ #rd,@loopbreak_writer = IO.pipe
381
+ @loopbreak_reader = UDPSocket.new
382
+ @loopbreak_writer = UDPSocket.new
383
+ bound = false
384
+ 100.times {
385
+ @loopbreak_port = rand(10000) + 40000
386
+ begin
387
+ @loopbreak_reader.bind "localhost", @loopbreak_port
388
+ bound = true
389
+ break
390
+ rescue
391
+ end
392
+ }
393
+ raise "Unable to bind Loopbreaker" unless bound
394
+ LoopbreakReader.new(@loopbreak_reader)
380
395
  end
381
396
 
382
397
  def close_loopbreaker
@@ -385,7 +400,8 @@ class Reactor
385
400
  end
386
401
 
387
402
  def signal_loopbreak
388
- @loopbreak_writer.write '+' if @loopbreak_writer
403
+ #@loopbreak_writer.write '+' if @loopbreak_writer
404
+ @loopbreak_writer.send('+',0,"localhost",@loopbreak_port) if @loopbreak_writer
389
405
  end
390
406
 
391
407
  def set_timer_quantum interval_in_seconds
@@ -428,8 +444,19 @@ module EventMachine
428
444
  @io = io
429
445
  @last_activity = Reactor.instance.current_loop_time
430
446
 
431
- m = @io.fcntl(Fcntl::F_GETFL, 0)
432
- @io.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK | m)
447
+ if defined?(Fcntl::F_GETFL)
448
+ m = @io.fcntl(Fcntl::F_GETFL, 0)
449
+ @io.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK | m)
450
+ else
451
+ # Windows doesn't define F_GETFL.
452
+ # It's not very reliable about setting descriptors nonblocking either.
453
+ begin
454
+ s = Socket.for_fd(@io.fileno)
455
+ s.fcntl( Fcntl::F_SETFL, Fcntl::O_NONBLOCK )
456
+ rescue Errno::EINVAL, Errno::EBADF
457
+ STDERR.puts "Serious error: unable to set descriptor non-blocking"
458
+ end
459
+ end
433
460
  # TODO, should set CLOEXEC on Unix?
434
461
 
435
462
  @close_scheduled = false
@@ -517,7 +544,7 @@ module EventMachine
517
544
  data = io.sysread(4096)
518
545
  EventMachine::event_callback uuid, ConnectionData, data
519
546
  end
520
- rescue Errno::EAGAIN
547
+ rescue Errno::EAGAIN, Errno::EWOULDBLOCK
521
548
  # no-op
522
549
  rescue Errno::ECONNRESET, Errno::ECONNREFUSED, EOFError
523
550
  @close_scheduled = true
@@ -1,4 +1,4 @@
1
- # $Id: header_and_content.rb 322 2007-05-22 22:18:35Z blackhedd $
1
+ # $Id: header_and_content.rb 668 2008-01-04 23:00:34Z blackhedd $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -1,4 +1,4 @@
1
- # $Id: httpcli2.rb 591 2007-12-03 20:48:44Z blackhedd $
1
+ # $Id: httpcli2.rb 668 2008-01-04 23:00:34Z blackhedd $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -1,4 +1,4 @@
1
- # $Id: httpclient.rb 518 2007-08-30 10:17:02Z blackhedd $
1
+ # $Id: httpclient.rb 668 2008-01-04 23:00:34Z blackhedd $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -1,4 +1,4 @@
1
- # $Id: line_and_text.rb 380 2007-06-13 19:10:15Z tarcieri $
1
+ # $Id: line_and_text.rb 668 2008-01-04 23:00:34Z blackhedd $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -1,4 +1,4 @@
1
- # $Id: linetext2.rb 486 2007-07-29 17:15:12Z blackhedd $
1
+ # $Id: linetext2.rb 668 2008-01-04 23:00:34Z blackhedd $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -1,4 +1,4 @@
1
- # $Id: saslauth.rb 568 2007-11-13 02:36:17Z blackhedd $
1
+ # $Id: saslauth.rb 668 2008-01-04 23:00:34Z blackhedd $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -107,6 +107,7 @@ module EventMachine
107
107
  end
108
108
  end
109
109
  end
110
+
110
111
  def validate username, psw, sysname, realm
111
112
  p username
112
113
  p psw
@@ -115,6 +116,63 @@ module EventMachine
115
116
  true
116
117
  end
117
118
  end
119
+
120
+ # Implements the SASL authd client protocol.
121
+ # This is a very, very simple protocol that mimics the one used
122
+ # by saslauthd and pwcheck, two outboard daemons included in the
123
+ # standard SASL library distro.
124
+ # The only thing this is really suitable for is SASL PLAIN
125
+ # (user+password) authentication, but the SASL libs that are
126
+ # linked into standard servers (like imapd and sendmail) implement
127
+ # the other ones.
128
+ #
129
+ # You can use this module directly as a handler for EM Connections,
130
+ # or include it in a module or handler class of your own.
131
+ #
132
+ # First connect to a SASL server (it's probably a TCP server, or more
133
+ # likely a Unix-domain socket). Then call the #validate? method,
134
+ # passing at least a username and a password. #validate? returns
135
+ # a Deferrable which will either succeed or fail, depending
136
+ # on the status of the authentication operation.
137
+ #
138
+ module SASLauthclient
139
+ MaxFieldSize = 128*1024
140
+
141
+ def validate? username, psw, sysname=nil, realm=nil
142
+
143
+ str = [username, psw, sysname, realm].map {|m|
144
+ [(m || "").length, (m || "")]
145
+ }.flatten.pack( "nA*" * 4 )
146
+ send_data str
147
+
148
+ d = EM::DefaultDeferrable.new
149
+ @queries.unshift d
150
+ d
151
+ end
152
+
153
+ def post_init
154
+ @sasl_data = ""
155
+ @queries = []
156
+ end
157
+
158
+ def receive_data data
159
+ @sasl_data << data
160
+
161
+ while @sasl_data.length > 2
162
+ len = (@sasl_data[0,2].unpack("n")).first
163
+ raise "SASL Max Field Length exceeded" if len > MaxFieldSize
164
+ if @sasl_data.length >= (len + 2)
165
+ val = @sasl_data[2,len]
166
+ @sasl_data.slice!(0...(2+len))
167
+ q = @queries.pop
168
+ (val == "NO") ? q.fail : q.succeed
169
+ else
170
+ break
171
+ end
172
+ end
173
+ end
174
+ end
175
+
118
176
  end
119
177
  end
120
178
 
@@ -1,4 +1,4 @@
1
- # $Id: smtpclient.rb 549 2007-09-22 00:49:42Z blackhedd $
1
+ # $Id: smtpclient.rb 668 2008-01-04 23:00:34Z blackhedd $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -24,7 +24,7 @@
24
24
  #
25
25
 
26
26
 
27
- require 'base64'
27
+ #require 'base64'
28
28
  require 'ostruct'
29
29
 
30
30
  module EventMachine
@@ -212,7 +212,8 @@ module Protocols
212
212
  if psw.respond_to?(:call)
213
213
  psw = psw.call
214
214
  end
215
- str = Base64::encode64("\0#{@args[:auth][:username]}\0#{psw}").chomp
215
+ #str = Base64::encode64("\0#{@args[:auth][:username]}\0#{psw}").chomp
216
+ str = ["\0#{@args[:auth][:username]}\0#{psw}"].pack("m").chomp
216
217
  send_data "AUTH PLAIN #{str}\r\n"
217
218
  @responder = :receive_auth_response
218
219
  else
@@ -1,4 +1,4 @@
1
- # $Id: smtpserver.rb 545 2007-09-19 21:07:28Z blackhedd $
1
+ # $Id: smtpserver.rb 668 2008-01-04 23:00:34Z blackhedd $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -24,7 +24,7 @@
24
24
  #
25
25
 
26
26
 
27
- require 'base64'
27
+ #require 'base64'
28
28
 
29
29
  module EventMachine
30
30
  module Protocols
@@ -254,7 +254,7 @@ module Protocols
254
254
  if @state.include?(:auth)
255
255
  send_data "503 auth already issued\r\n"
256
256
  elsif str =~ /\APLAIN\s+/i
257
- plain = Base64::decode64($'.dup)
257
+ plain = ($'.dup).unpack("m").first # Base64::decode64($'.dup)
258
258
  discard,user,psw = plain.split("\000")
259
259
  if receive_plain_auth user,psw
260
260
  send_data "235 authentication ok\r\n"
@@ -1,4 +1,4 @@
1
- # $Id: stomp.rb 488 2007-07-30 05:09:40Z blackhedd $
1
+ # $Id: stomp.rb 668 2008-01-04 23:00:34Z blackhedd $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -1,4 +1,4 @@
1
- # $Id: tcptest.rb 322 2007-05-22 22:18:35Z blackhedd $
1
+ # $Id: tcptest.rb 668 2008-01-04 23:00:34Z blackhedd $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
data/tests/test_basic.rb CHANGED
@@ -1,4 +1,4 @@
1
- # $Id: test_basic.rb 607 2007-12-09 20:59:12Z blackhedd $
1
+ # $Id: test_basic.rb 668 2008-01-04 23:00:34Z blackhedd $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -26,6 +26,7 @@
26
26
 
27
27
  $:.unshift "../lib"
28
28
  require 'eventmachine'
29
+ require 'test/unit'
29
30
 
30
31
  class TestBasic < Test::Unit::TestCase
31
32
 
@@ -0,0 +1,63 @@
1
+ # $Id: test_defer.rb 668 2008-01-04 23:00:34Z blackhedd $
2
+ #
3
+ # Author:: Francis Cianfrocca (gmail: blackhedd)
4
+ # Homepage:: http://rubyeventmachine.com
5
+ # Date:: 8 April 2006
6
+ #
7
+ # See EventMachine and EventMachine::Connection for documentation and
8
+ # usage examples.
9
+ #
10
+ #----------------------------------------------------------------------------
11
+ #
12
+ # Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
13
+ # Gmail: blackhedd
14
+ #
15
+ # This program is free software; you can redistribute it and/or modify
16
+ # it under the terms of either: 1) the GNU General Public License
17
+ # as published by the Free Software Foundation; either version 2 of the
18
+ # License, or (at your option) any later version; or 2) Ruby's License.
19
+ #
20
+ # See the file COPYING for complete licensing information.
21
+ #
22
+ #---------------------------------------------------------------------------
23
+ #
24
+ #
25
+ #
26
+
27
+ $:.unshift "../lib"
28
+ require 'eventmachine'
29
+ require 'test/unit'
30
+
31
+ class TestDeferUsage < Test::Unit::TestCase
32
+
33
+ def setup
34
+ end
35
+
36
+ def teardown
37
+ end
38
+
39
+ def run_em_with_defers
40
+ n = 0
41
+ n_times = 20
42
+ EM.run {
43
+ n_times.times {
44
+ EM.defer proc {
45
+ sleep 0.1
46
+ }, proc {
47
+ n += 1
48
+ EM.stop if n == n_times
49
+ }
50
+ }
51
+ }
52
+ assert_equal( n, n_times )
53
+ end
54
+ def test_defers
55
+ 10.times {
56
+ run_em_with_defers {|n,ntimes|
57
+ assert_equal( n, ntimes )
58
+ }
59
+ }
60
+ end
61
+
62
+ end
63
+
data/tests/test_epoll.rb CHANGED
@@ -1,4 +1,4 @@
1
- # $Id: test_epoll.rb 599 2007-12-05 14:24:11Z blackhedd $
1
+ # $Id: test_epoll.rb 668 2008-01-04 23:00:34Z blackhedd $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -30,7 +30,7 @@
30
30
 
31
31
  $:.unshift "../lib"
32
32
  require 'eventmachine'
33
-
33
+ require 'test/unit'
34
34
 
35
35
 
36
36
  class TestEpoll < Test::Unit::TestCase
@@ -148,12 +148,16 @@ class TestEpoll < Test::Unit::TestCase
148
148
  # Pure Ruby also oddly won't let us make that many connections. This test used
149
149
  # to run 100 times. Not sure where that lower connection-limit is coming from in
150
150
  # pure Ruby.
151
- File.unlink("./xxx.chain")
152
- EM.start_unix_domain_server "./xxx.chain", TestEchoServer
151
+ # Let's not sweat the Unix-ness of the filename, since this test can't possibly
152
+ # work on Windows anyway.
153
+ #
154
+ fn = "/tmp/xxx.chain"
155
+ File.unlink(fn) if File.exist?(fn)
156
+ EM.start_unix_domain_server fn, TestEchoServer
153
157
  $n = 0
154
158
  $max = 0
155
159
  50.times {
156
- EM.connect_unix_domain("./xxx.chain", TestEchoClient) {$n += 1}
160
+ EM.connect_unix_domain(fn, TestEchoClient) {$n += 1}
157
161
  }
158
162
  }
159
163
  assert_equal(0, $n)
@@ -161,3 +165,4 @@ class TestEpoll < Test::Unit::TestCase
161
165
  end
162
166
 
163
167
  end
168
+
data/tests/test_errors.rb CHANGED
@@ -1,4 +1,4 @@
1
- # $Id: test_errors.rb 557 2007-10-03 07:21:02Z blackhedd $
1
+ # $Id: test_errors.rb 668 2008-01-04 23:00:34Z blackhedd $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -24,8 +24,15 @@
24
24
  #
25
25
  #
26
26
 
27
+
28
+ ###### THIS TEST IS NOW OBSOLETE.
29
+ ###### As of 27Dec07, the hookable error handling is obsolete because
30
+ ###### of its performance impact.
31
+
32
+
27
33
  $:.unshift "../lib"
28
34
  require 'eventmachine'
35
+ require 'test/unit'
29
36
 
30
37
  class TestErrors < Test::Unit::TestCase
31
38
 
@@ -42,13 +49,16 @@ class TestErrors < Test::Unit::TestCase
42
49
  EM.set_runtime_error_hook
43
50
  end
44
51
 
52
+ def test_a
53
+ end
54
+
45
55
  # EM has a default handler for RuntimeErrors that are emitted from
46
56
  # user written code. You can override the handler if you wish, but it's
47
57
  # easier to call #set_runtime_error_hook.
48
58
  # Ordinarily, an error in user code invoked by the reactor aborts the
49
59
  # run.
50
60
  #
51
- def test_unhandled_error
61
+ def obsolete_test_unhandled_error
52
62
  assert_raise( RuntimeError ) {
53
63
  EM.run {
54
64
  EM.add_timer(0) {raise "AAA"}
@@ -57,7 +67,7 @@ class TestErrors < Test::Unit::TestCase
57
67
 
58
68
  end
59
69
 
60
- def test_handled_error
70
+ def obsolete_test_handled_error
61
71
  err = nil
62
72
  EM.run {
63
73
  EM.set_runtime_error_hook {
@@ -1,4 +1,4 @@
1
- # $Id: test_eventables.rb 399 2007-07-11 02:50:20Z blackhedd $
1
+ # $Id: test_eventables.rb 668 2008-01-04 23:00:34Z blackhedd $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
data/tests/test_exc.rb CHANGED
@@ -1,4 +1,4 @@
1
- # $Id: test_exc.rb 323 2007-05-22 22:22:43Z blackhedd $
1
+ # $Id: test_exc.rb 668 2008-01-04 23:00:34Z blackhedd $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -25,6 +25,7 @@
25
25
 
26
26
  $:.unshift "../lib"
27
27
  require 'eventmachine'
28
+ require 'test/unit'
28
29
 
29
30
  class TestSomeExceptions < Test::Unit::TestCase
30
31