eventmachine 0.10.0 → 0.12.0

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