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.
- data/DEFERRABLES +1 -1
- data/LIGHTWEIGHT_CONCURRENCY +1 -1
- data/PURE_RUBY +1 -1
- data/README +1 -1
- data/RELEASE_NOTES +1 -1
- data/SMTP +1 -1
- data/SPAWNED_PROCESSES +1 -1
- data/TODO +1 -1
- data/ext/binder.cpp +1 -1
- data/ext/binder.h +1 -1
- data/ext/cmain.cpp +29 -1
- data/ext/cplusplus.cpp +1 -1
- data/ext/ed.cpp +79 -1
- data/ext/ed.h +6 -1
- data/ext/em.cpp +343 -27
- data/ext/em.h +25 -1
- data/ext/emwin.cpp +1 -1
- data/ext/emwin.h +1 -1
- data/ext/epoll.cpp +1 -1
- data/ext/epoll.h +1 -1
- data/ext/eventmachine.h +3 -1
- data/ext/eventmachine_cpp.h +1 -1
- data/ext/extconf.rb +31 -1
- data/ext/files.cpp +1 -1
- data/ext/files.h +1 -1
- data/ext/kb.cpp +4 -1
- data/ext/page.cpp +1 -1
- data/ext/page.h +1 -1
- data/ext/pipe.cpp +4 -1
- data/ext/project.h +8 -2
- data/ext/rubymain.cpp +73 -2
- data/ext/sigs.cpp +1 -1
- data/ext/sigs.h +1 -1
- data/ext/ssl.cpp +4 -1
- data/ext/ssl.h +1 -1
- data/lib/em/deferrable.rb +1 -1
- data/lib/em/eventable.rb +1 -1
- data/lib/em/future.rb +1 -1
- data/lib/em/messages.rb +1 -1
- data/lib/em/processes.rb +68 -0
- data/lib/em/spawnable.rb +1 -1
- data/lib/em/streamer.rb +1 -1
- data/lib/eventmachine.rb +113 -66
- data/lib/eventmachine_version.rb +2 -2
- data/lib/evma.rb +1 -1
- data/lib/evma/callback.rb +1 -1
- data/lib/evma/container.rb +1 -1
- data/lib/evma/factory.rb +1 -1
- data/lib/evma/protocol.rb +1 -1
- data/lib/evma/reactor.rb +1 -1
- data/lib/jeventmachine.rb +1 -1
- data/lib/pr_eventmachine.rb +35 -8
- data/lib/protocols/header_and_content.rb +1 -1
- data/lib/protocols/httpcli2.rb +1 -1
- data/lib/protocols/httpclient.rb +1 -1
- data/lib/protocols/line_and_text.rb +1 -1
- data/lib/protocols/linetext2.rb +1 -1
- data/lib/protocols/saslauth.rb +59 -1
- data/lib/protocols/smtpclient.rb +4 -3
- data/lib/protocols/smtpserver.rb +3 -3
- data/lib/protocols/stomp.rb +1 -1
- data/lib/protocols/tcptest.rb +1 -1
- data/tests/test_basic.rb +2 -1
- data/tests/test_defer.rb +63 -0
- data/tests/test_epoll.rb +10 -5
- data/tests/test_errors.rb +13 -3
- data/tests/test_eventables.rb +1 -1
- data/tests/test_exc.rb +2 -1
- data/tests/test_futures.rb +2 -1
- data/tests/test_hc.rb +26 -2
- data/tests/test_httpclient.rb +2 -1
- data/tests/test_httpclient2.rb +2 -1
- data/tests/test_kb.rb +2 -1
- data/tests/test_ltp.rb +3 -1
- data/tests/test_ltp2.rb +2 -1
- data/tests/test_next_tick.rb +2 -1
- data/tests/test_processes.rb +56 -0
- data/tests/test_pure.rb +2 -1
- data/tests/test_running.rb +2 -1
- data/tests/test_sasl.rb +73 -0
- data/tests/test_send_file.rb +3 -1
- data/tests/test_servers.rb +4 -1
- data/tests/test_smtpclient.rb +2 -1
- data/tests/test_smtpserver.rb +3 -2
- data/tests/test_spawn.rb +2 -1
- data/tests/test_timers.rb +2 -2
- data/tests/test_ud.rb +2 -1
- data/tests/testem.rb +1 -1
- metadata +115 -104
data/lib/jeventmachine.rb
CHANGED
data/lib/pr_eventmachine.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: pr_eventmachine.rb
|
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
|
-
|
378
|
-
|
379
|
-
|
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
|
-
|
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
|
-
|
432
|
-
|
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
|
data/lib/protocols/httpcli2.rb
CHANGED
data/lib/protocols/httpclient.rb
CHANGED
data/lib/protocols/linetext2.rb
CHANGED
data/lib/protocols/saslauth.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: saslauth.rb
|
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
|
|
data/lib/protocols/smtpclient.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: smtpclient.rb
|
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
|
data/lib/protocols/smtpserver.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: smtpserver.rb
|
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"
|
data/lib/protocols/stomp.rb
CHANGED
data/lib/protocols/tcptest.rb
CHANGED
data/tests/test_basic.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: test_basic.rb
|
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
|
|
data/tests/test_defer.rb
ADDED
@@ -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
|
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
|
-
|
152
|
-
|
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(
|
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
|
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
|
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
|
70
|
+
def obsolete_test_handled_error
|
61
71
|
err = nil
|
62
72
|
EM.run {
|
63
73
|
EM.set_runtime_error_hook {
|
data/tests/test_eventables.rb
CHANGED
data/tests/test_exc.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: test_exc.rb
|
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
|
|