eventmachine 0.9.0 → 0.10.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 +3 -3
- data/PURE_RUBY +77 -0
- data/ext/cmain.cpp +41 -2
- data/ext/ed.cpp +67 -3
- data/ext/ed.h +4 -1
- data/ext/em.cpp +33 -10
- data/ext/em.h +6 -14
- data/ext/eventmachine.h +4 -1
- data/ext/pipe.cpp +21 -3
- data/ext/rubymain.cpp +38 -1
- data/ext/ssl.cpp +9 -3
- data/lib/em/streamer.rb +1 -3
- data/lib/eventmachine.rb +190 -38
- data/lib/eventmachine_version.rb +2 -2
- data/lib/pr_eventmachine.rb +309 -28
- data/lib/protocols/httpcli2.rb +784 -0
- data/lib/protocols/saslauth.rb +121 -0
- data/lib/protocols/smtpclient.rb +41 -10
- data/lib/protocols/smtpserver.rb +30 -1
- data/tests/test_basic.rb +33 -2
- data/tests/test_epoll.rb +9 -3
- data/tests/test_errors.rb +72 -0
- data/tests/test_httpclient2.rb +132 -0
- data/tests/test_pure.rb +127 -0
- data/tests/test_timers.rb +30 -1
- metadata +37 -32
- data/ext/eee +0 -173
- data/lib/svn-commit.tmp +0 -4
data/ext/pipe.cpp
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*****************************************************************************
|
2
2
|
|
3
|
-
$Id: pipe.cpp
|
3
|
+
$Id: pipe.cpp 585 2007-11-27 14:29:34Z blackhedd $
|
4
4
|
|
5
5
|
File: pipe.cpp
|
6
6
|
Date: 30May07
|
@@ -71,15 +71,32 @@ PipeDescriptor::~PipeDescriptor()
|
|
71
71
|
* Since we want to have a signal processor integrated into the
|
72
72
|
* client-visible API, let's wait until that is done before cleaning
|
73
73
|
* this up.
|
74
|
+
*
|
75
|
+
* Added a very ugly hack to support passing the subprocess's exit
|
76
|
+
* status to the user. It only makes logical sense for user code to access
|
77
|
+
* the subprocess exit status in the unbind callback. But unbind is called
|
78
|
+
* back during the EventableDescriptor destructor. So by that time there's
|
79
|
+
* no way to call back this object through an object binding, because it's
|
80
|
+
* already been cleaned up. We might have added a parameter to the unbind
|
81
|
+
* callback, but that would probably break a huge amount of existing code.
|
82
|
+
* So the hack-solution is to define an instance variable in the EventMachine
|
83
|
+
* object and stick the exit status in there, where it can easily be accessed
|
84
|
+
* with an accessor visible to user code.
|
85
|
+
* User code should ONLY access the exit status from within the unbind callback.
|
86
|
+
* Otherwise there's no guarantee it'll be valid.
|
87
|
+
* This hack won't make it impossible to run multiple EventMachines in a single
|
88
|
+
* process, but it will make it impossible to reliably nest unbind calls
|
89
|
+
* within other unbind calls. (Not sure if that's even possible.)
|
74
90
|
*/
|
75
91
|
|
76
92
|
struct timespec req = {0, 10000000};
|
77
93
|
kill (SubprocessPid, SIGTERM);
|
78
94
|
nanosleep (&req, NULL);
|
79
|
-
|
95
|
+
assert (MyEventMachine);
|
96
|
+
if (waitpid (SubprocessPid, &(MyEventMachine->SubprocessExitStatus), WNOHANG) == 0) {
|
80
97
|
kill (SubprocessPid, SIGKILL);
|
81
98
|
nanosleep (&req, NULL);
|
82
|
-
if (waitpid (SubprocessPid,
|
99
|
+
if (waitpid (SubprocessPid, &(MyEventMachine->SubprocessExitStatus), WNOHANG) == 0)
|
83
100
|
throw std::runtime_error ("unable to reap subprocess");
|
84
101
|
}
|
85
102
|
}
|
@@ -302,5 +319,6 @@ bool PipeDescriptor::GetSubprocessPid (pid_t *pid)
|
|
302
319
|
return ok;
|
303
320
|
}
|
304
321
|
|
322
|
+
|
305
323
|
#endif // OS_UNIX
|
306
324
|
|
data/ext/rubymain.cpp
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*****************************************************************************
|
2
2
|
|
3
|
-
$Id: rubymain.cpp
|
3
|
+
$Id: rubymain.cpp 584 2007-11-27 07:27:32Z blackhedd $
|
4
4
|
|
5
5
|
File: rubymain.cpp
|
6
6
|
Date: 06Apr06
|
@@ -181,6 +181,20 @@ static VALUE t_get_subprocess_pid (VALUE self, VALUE signature)
|
|
181
181
|
return Qnil;
|
182
182
|
}
|
183
183
|
|
184
|
+
/***********************
|
185
|
+
t_get_subprocess_status
|
186
|
+
***********************/
|
187
|
+
|
188
|
+
static VALUE t_get_subprocess_status (VALUE self, VALUE signature)
|
189
|
+
{
|
190
|
+
int status;
|
191
|
+
if (evma_get_subprocess_status (StringValuePtr (signature), &status)) {
|
192
|
+
return INT2NUM (status);
|
193
|
+
}
|
194
|
+
|
195
|
+
return Qnil;
|
196
|
+
}
|
197
|
+
|
184
198
|
/*****************************
|
185
199
|
t_get_comm_inactivity_timeout
|
186
200
|
*****************************/
|
@@ -227,6 +241,16 @@ static VALUE t_close_connection (VALUE self, VALUE signature, VALUE after_writin
|
|
227
241
|
return Qnil;
|
228
242
|
}
|
229
243
|
|
244
|
+
/********************************
|
245
|
+
t_report_connection_error_status
|
246
|
+
********************************/
|
247
|
+
|
248
|
+
static VALUE t_report_connection_error_status (VALUE self, VALUE signature)
|
249
|
+
{
|
250
|
+
int b = evma_report_connection_error_status (StringValuePtr (signature));
|
251
|
+
return INT2NUM (b);
|
252
|
+
}
|
253
|
+
|
230
254
|
|
231
255
|
|
232
256
|
/****************
|
@@ -323,6 +347,16 @@ static VALUE t_set_timer_quantum (VALUE self, VALUE interval)
|
|
323
347
|
return Qnil;
|
324
348
|
}
|
325
349
|
|
350
|
+
/********************
|
351
|
+
t_set_max_timer_count
|
352
|
+
********************/
|
353
|
+
|
354
|
+
static VALUE t_set_max_timer_count (VALUE self, VALUE ct)
|
355
|
+
{
|
356
|
+
evma_set_max_timer_count (FIX2INT (ct));
|
357
|
+
return Qnil;
|
358
|
+
}
|
359
|
+
|
326
360
|
/***************
|
327
361
|
t_setuid_string
|
328
362
|
***************/
|
@@ -485,6 +519,7 @@ extern "C" void Init_rubyeventmachine()
|
|
485
519
|
rb_define_module_function (EmModule, "send_data", (VALUE(*)(...))t_send_data, 3);
|
486
520
|
rb_define_module_function (EmModule, "send_datagram", (VALUE(*)(...))t_send_datagram, 5);
|
487
521
|
rb_define_module_function (EmModule, "close_connection", (VALUE(*)(...))t_close_connection, 2);
|
522
|
+
rb_define_module_function (EmModule, "report_connection_error_status", (VALUE(*)(...))t_report_connection_error_status, 1);
|
488
523
|
rb_define_module_function (EmModule, "connect_server", (VALUE(*)(...))t_connect_server, 2);
|
489
524
|
rb_define_module_function (EmModule, "connect_unix_server", (VALUE(*)(...))t_connect_unix_server, 1);
|
490
525
|
rb_define_module_function (EmModule, "open_udp_socket", (VALUE(*)(...))t_open_udp_socket, 2);
|
@@ -494,6 +529,7 @@ extern "C" void Init_rubyeventmachine()
|
|
494
529
|
rb_define_module_function (EmModule, "signal_loopbreak", (VALUE(*)(...))t_signal_loopbreak, 0);
|
495
530
|
rb_define_module_function (EmModule, "library_type", (VALUE(*)(...))t_library_type, 0);
|
496
531
|
rb_define_module_function (EmModule, "set_timer_quantum", (VALUE(*)(...))t_set_timer_quantum, 1);
|
532
|
+
rb_define_module_function (EmModule, "set_max_timer_count", (VALUE(*)(...))t_set_max_timer_count, 1);
|
497
533
|
rb_define_module_function (EmModule, "setuid_string", (VALUE(*)(...))t_setuid_string, 1);
|
498
534
|
rb_define_module_function (EmModule, "invoke_popen", (VALUE(*)(...))t_invoke_popen, 1);
|
499
535
|
rb_define_module_function (EmModule, "send_file_data", (VALUE(*)(...))t_send_file_data, 2);
|
@@ -503,6 +539,7 @@ extern "C" void Init_rubyeventmachine()
|
|
503
539
|
|
504
540
|
rb_define_module_function (EmModule, "get_peername", (VALUE(*)(...))t_get_peername, 1);
|
505
541
|
rb_define_module_function (EmModule, "get_subprocess_pid", (VALUE(*)(...))t_get_subprocess_pid, 1);
|
542
|
+
rb_define_module_function (EmModule, "get_subprocess_status", (VALUE(*)(...))t_get_subprocess_status, 1);
|
506
543
|
rb_define_module_function (EmModule, "get_comm_inactivity_timeout", (VALUE(*)(...))t_get_comm_inactivity_timeout, 1);
|
507
544
|
rb_define_module_function (EmModule, "set_comm_inactivity_timeout", (VALUE(*)(...))t_set_comm_inactivity_timeout, 2);
|
508
545
|
rb_define_module_function (EmModule, "set_rlimit_nofile", (VALUE(*)(...))t_set_rlimit_nofile, 1);
|
data/ext/ssl.cpp
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*****************************************************************************
|
2
2
|
|
3
|
-
$Id: ssl.cpp
|
3
|
+
$Id: ssl.cpp 574 2007-11-19 23:36:04Z blackhedd $
|
4
4
|
|
5
5
|
File: ssl.cpp
|
6
6
|
Date: 30Apr06
|
@@ -155,9 +155,15 @@ SslContext_t::SslContext_t (bool is_server, const string &privkeyfile, const str
|
|
155
155
|
if (is_server) {
|
156
156
|
// The SSL_CTX calls here do NOT allocate memory.
|
157
157
|
int e;
|
158
|
-
|
158
|
+
if (privkeyfile.length() > 0)
|
159
|
+
e = SSL_CTX_use_PrivateKey_file (pCtx, privkeyfile.c_str(), SSL_FILETYPE_PEM);
|
160
|
+
else
|
161
|
+
e = SSL_CTX_use_PrivateKey (pCtx, DefaultPrivateKey);
|
159
162
|
assert (e > 0);
|
160
|
-
|
163
|
+
if (certchainfile.length() > 0)
|
164
|
+
e = SSL_CTX_use_certificate_chain_file (pCtx, certchainfile.c_str());
|
165
|
+
else
|
166
|
+
e = SSL_CTX_use_certificate (pCtx, DefaultCertificate);
|
161
167
|
assert (e > 0);
|
162
168
|
}
|
163
169
|
|
data/lib/em/streamer.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: streamer.rb
|
1
|
+
# $Id: streamer.rb 599 2007-12-05 14:24:11Z blackhedd $
|
2
2
|
#
|
3
3
|
# Author:: Francis Cianfrocca (gmail: blackhedd)
|
4
4
|
# Homepage:: http://rubyeventmachine.com
|
@@ -49,7 +49,6 @@ module EventMachine
|
|
49
49
|
|
50
50
|
def stream_without_mapping filename
|
51
51
|
if @http_chunks
|
52
|
-
#@connection.send_data "#{format("%x",@size)}\r\n"
|
53
52
|
@connection.send_data "#{@size.to_s(16)}\r\n"
|
54
53
|
@connection.send_file_data filename
|
55
54
|
@connection.send_data "\r\n0\r\n\r\n"
|
@@ -79,7 +78,6 @@ module EventMachine
|
|
79
78
|
len = @size - @position
|
80
79
|
len = ChunkSize if (len > ChunkSize)
|
81
80
|
|
82
|
-
#@connection.send_data( "#{format("%x",len)}\r\n" ) if @http_chunks
|
83
81
|
@connection.send_data( "#{len.to_s(16)}\r\n" ) if @http_chunks
|
84
82
|
@connection.send_data( @mapping.get_chunk( @position, len ))
|
85
83
|
@connection.send_data("\r\n") if @http_chunks
|
data/lib/eventmachine.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: eventmachine.rb
|
1
|
+
# $Id: eventmachine.rb 594 2007-12-05 11:41:39Z blackhedd $
|
2
2
|
#
|
3
3
|
# Author:: Francis Cianfrocca (gmail: blackhedd)
|
4
4
|
# Homepage:: http://rubyeventmachine.com
|
@@ -32,6 +32,14 @@
|
|
32
32
|
# till now. The reason I'm disabling it is because the pure-Ruby
|
33
33
|
# code will have problems of its own, and it's not nearly as fast
|
34
34
|
# anyway. Suggested by a problem report from Moshe Litvin. 05Jun07.
|
35
|
+
#
|
36
|
+
# 05Dec07: Re-enabled the pure-ruby mechanism, but without the automatic
|
37
|
+
# fallback feature that tripped up Moshe Litvin. We shouldn't fail over to
|
38
|
+
# the pure Ruby version because it's possible that the user intended to
|
39
|
+
# run the extension but failed to do so because of a compilation or
|
40
|
+
# similar error. So we require either a global variable or an environment
|
41
|
+
# string be set in order to select the pure-Ruby version.
|
42
|
+
#
|
35
43
|
|
36
44
|
=begin
|
37
45
|
$eventmachine_library ||= nil
|
@@ -56,7 +64,11 @@ if RUBY_PLATFORM =~ /java/
|
|
56
64
|
require 'java'
|
57
65
|
require 'jeventmachine'
|
58
66
|
else
|
59
|
-
|
67
|
+
if $eventmachine_library == :pure_ruby or ENV['EVENTMACHINE_LIBRARY'] == "pure_ruby"
|
68
|
+
require 'pr_eventmachine'
|
69
|
+
else
|
70
|
+
require 'rubyeventmachine'
|
71
|
+
end
|
60
72
|
end
|
61
73
|
|
62
74
|
|
@@ -153,17 +165,6 @@ require 'shellwords'
|
|
153
165
|
#
|
154
166
|
#
|
155
167
|
# == Questions and Futures
|
156
|
-
# Encryption: EventMachine needs the capability to run SSL/TLS on any
|
157
|
-
# of its clients and servers. Coming soon.
|
158
|
-
#
|
159
|
-
# <tt>epoll(4):</tt> EventMachine currently is based on the <tt>select(2)</tt>
|
160
|
-
# system call in order to be compatible with the widest variety of platforms,
|
161
|
-
# but it would be interesting to re-base it on <tt>epoll(4).</tt>
|
162
|
-
# While requiring a Linux 2.6 kernel, this might possibly give much better
|
163
|
-
# performance and scalability. EventMachine's C++ antecedents already work
|
164
|
-
# with <tt>kqueue</tt> from the BSD world, but it's not yet clear that this
|
165
|
-
# is worth doing. Depends on how many people ask for it.
|
166
|
-
#
|
167
168
|
# Would it be useful for EventMachine to incorporate the Observer pattern
|
168
169
|
# and make use of the corresponding Ruby <tt>observer</tt> package?
|
169
170
|
# Interesting thought.
|
@@ -483,15 +484,21 @@ module EventMachine
|
|
483
484
|
# }
|
484
485
|
#
|
485
486
|
#
|
486
|
-
def EventMachine::start_server server, port, handler=nil, &block
|
487
|
+
def EventMachine::start_server server, port, handler=nil, *args, &block
|
487
488
|
klass = if (handler and handler.is_a?(Class))
|
488
489
|
handler
|
489
490
|
else
|
490
491
|
Class.new( Connection ) {handler and include handler}
|
491
492
|
end
|
492
493
|
|
494
|
+
arity = klass.instance_method(:initialize).arity
|
495
|
+
expected = arity >= 0 ? arity : -(arity + 1)
|
496
|
+
if (arity >= 0 and args.size != expected) or (arity < 0 and args.size < expected)
|
497
|
+
raise ArgumentError, "wrong number of arguments for #{klass}#initialize (#{args.size} for #{expected})"
|
498
|
+
end
|
499
|
+
|
493
500
|
s = start_tcp_server server, port
|
494
|
-
@acceptors[s] = [klass,block]
|
501
|
+
@acceptors[s] = [klass,args,block]
|
495
502
|
s
|
496
503
|
end
|
497
504
|
|
@@ -505,15 +512,21 @@ module EventMachine
|
|
505
512
|
EventMachine::stop_tcp_server signature
|
506
513
|
end
|
507
514
|
|
508
|
-
def EventMachine::start_unix_domain_server filename, handler=nil, &block
|
515
|
+
def EventMachine::start_unix_domain_server filename, handler=nil, *args, &block
|
509
516
|
klass = if (handler and handler.is_a?(Class))
|
510
517
|
handler
|
511
518
|
else
|
512
519
|
Class.new( Connection ) {handler and include handler}
|
513
520
|
end
|
514
521
|
|
522
|
+
arity = klass.instance_method(:initialize).arity
|
523
|
+
expected = arity >= 0 ? arity : -(arity + 1)
|
524
|
+
if (arity >= 0 and args.size != expected) or (arity < 0 and args.size < expected)
|
525
|
+
raise ArgumentError, "wrong number of arguments for #{klass}#initialize (#{args.size} for #{expected})"
|
526
|
+
end
|
527
|
+
|
515
528
|
s = start_unix_server filename
|
516
|
-
@acceptors[s] = [klass,block]
|
529
|
+
@acceptors[s] = [klass,args,block]
|
517
530
|
end
|
518
531
|
|
519
532
|
# EventMachine#connect initiates a TCP connection to a remote
|
@@ -613,16 +626,21 @@ module EventMachine
|
|
613
626
|
# to have them behave differently with respect to post_init
|
614
627
|
# if at all possible.
|
615
628
|
#
|
616
|
-
def EventMachine::connect server, port, handler=nil
|
617
|
-
|
629
|
+
def EventMachine::connect server, port, handler=nil, *args
|
618
630
|
klass = if (handler and handler.is_a?(Class))
|
619
631
|
handler
|
620
632
|
else
|
621
633
|
Class.new( Connection ) {handler and include handler}
|
622
634
|
end
|
623
635
|
|
636
|
+
arity = klass.instance_method(:initialize).arity
|
637
|
+
expected = arity >= 0 ? arity : -(arity + 1)
|
638
|
+
if (arity >= 0 and args.size != expected) or (arity < 0 and args.size < expected)
|
639
|
+
raise ArgumentError, "wrong number of arguments for #{klass}#initialize (#{args.size} for #{expected})"
|
640
|
+
end
|
641
|
+
|
624
642
|
s = connect_server server, port
|
625
|
-
c = klass.new s
|
643
|
+
c = klass.new s, *args
|
626
644
|
@conns[s] = c
|
627
645
|
block_given? and yield c
|
628
646
|
c
|
@@ -668,15 +686,21 @@ module EventMachine
|
|
668
686
|
# For making connections to Unix-domain sockets.
|
669
687
|
# Eventually this has to get properly documented and unified with the TCP-connect methods.
|
670
688
|
# Note how nearly identical this is to EventMachine#connect
|
671
|
-
def EventMachine::connect_unix_domain socketname, handler=nil
|
689
|
+
def EventMachine::connect_unix_domain socketname, handler=nil, *args
|
672
690
|
klass = if (handler and handler.is_a?(Class))
|
673
691
|
handler
|
674
692
|
else
|
675
693
|
Class.new( Connection ) {handler and include handler}
|
676
694
|
end
|
677
695
|
|
696
|
+
arity = klass.instance_method(:initialize).arity
|
697
|
+
expected = arity >= 0 ? arity : -(arity + 1)
|
698
|
+
if (arity >= 0 and args.size != expected) or (arity < 0 and args.size < expected)
|
699
|
+
raise ArgumentError, "wrong number of arguments for #{klass}#initialize (#{args.size} for #{expected})"
|
700
|
+
end
|
701
|
+
|
678
702
|
s = connect_unix_server socketname
|
679
|
-
c = klass.new s
|
703
|
+
c = klass.new s, *args
|
680
704
|
@conns[s] = c
|
681
705
|
block_given? and yield c
|
682
706
|
c
|
@@ -746,15 +770,21 @@ module EventMachine
|
|
746
770
|
# Replaced the implementation on 01Oct06. Thanks to Tobias Gustafsson for pointing
|
747
771
|
# out that this originally did not take a class but only a module.
|
748
772
|
#
|
749
|
-
def self::open_datagram_socket address, port, handler=nil
|
773
|
+
def self::open_datagram_socket address, port, handler=nil, *args
|
750
774
|
klass = if (handler and handler.is_a?(Class))
|
751
775
|
handler
|
752
776
|
else
|
753
777
|
Class.new( Connection ) {handler and include handler}
|
754
778
|
end
|
755
779
|
|
780
|
+
arity = klass.instance_method(:initialize).arity
|
781
|
+
expected = arity >= 0 ? arity : -(arity + 1)
|
782
|
+
if (arity >= 0 and args.size != expected) or (arity < 0 and args.size < expected)
|
783
|
+
raise ArgumentError, "wrong number of arguments for #{klass}#initialize (#{args.size} for #{expected})"
|
784
|
+
end
|
785
|
+
|
756
786
|
s = open_udp_socket address, port
|
757
|
-
c = klass.new s
|
787
|
+
c = klass.new s, *args
|
758
788
|
@conns[s] = c
|
759
789
|
block_given? and yield c
|
760
790
|
c
|
@@ -777,6 +807,14 @@ module EventMachine
|
|
777
807
|
set_timer_quantum mills.to_i
|
778
808
|
end
|
779
809
|
|
810
|
+
# Sets the maximum number of timers and periodic timers that may be outstanding at any
|
811
|
+
# given time. You only need to call #set_max_timers if you need more than the default
|
812
|
+
# number of timers, which on most platforms is 1000.
|
813
|
+
# Call this method before calling EventMachine#run.
|
814
|
+
#
|
815
|
+
def self::set_max_timers ct
|
816
|
+
set_max_timer_count ct
|
817
|
+
end
|
780
818
|
|
781
819
|
#--
|
782
820
|
# The is the responder for the loopback-signalled event.
|
@@ -1007,36 +1045,97 @@ module EventMachine
|
|
1007
1045
|
|
1008
1046
|
private
|
1009
1047
|
def EventMachine::event_callback conn_binding, opcode, data
|
1048
|
+
#
|
1049
|
+
# Added 03Oct07: Any code path that invokes user-written code must
|
1050
|
+
# wrap itself in a begin/rescue for RuntimeErrors, that calls the
|
1051
|
+
# user-overridable class method #handle_runtime_error.
|
1052
|
+
#
|
1010
1053
|
if opcode == ConnectionData
|
1011
1054
|
c = @conns[conn_binding] or raise ConnectionNotBound
|
1012
|
-
|
1055
|
+
begin
|
1056
|
+
c.receive_data data
|
1057
|
+
rescue
|
1058
|
+
EventMachine.handle_runtime_error
|
1059
|
+
end
|
1013
1060
|
elsif opcode == ConnectionUnbound
|
1014
1061
|
if c = @conns.delete( conn_binding )
|
1015
|
-
|
1062
|
+
begin
|
1063
|
+
c.unbind
|
1064
|
+
rescue
|
1065
|
+
EventMachine.handle_runtime_error
|
1066
|
+
end
|
1016
1067
|
elsif c = @acceptors.delete( conn_binding )
|
1017
1068
|
# no-op
|
1018
1069
|
else
|
1019
1070
|
raise ConnectionNotBound
|
1020
1071
|
end
|
1021
1072
|
elsif opcode == ConnectionAccepted
|
1022
|
-
accep,blk = @acceptors[conn_binding]
|
1073
|
+
accep,args,blk = @acceptors[conn_binding]
|
1023
1074
|
raise NoHandlerForAcceptedConnection unless accep
|
1024
|
-
c = accep.new data
|
1075
|
+
c = accep.new data, *args
|
1025
1076
|
@conns[data] = c
|
1026
|
-
|
1077
|
+
begin
|
1078
|
+
blk and blk.call(c)
|
1079
|
+
rescue
|
1080
|
+
EventMachine.handle_runtime_error
|
1081
|
+
end
|
1027
1082
|
c # (needed?)
|
1028
1083
|
elsif opcode == TimerFired
|
1029
1084
|
t = @timers.delete( data ) or raise UnknownTimerFired
|
1030
|
-
|
1085
|
+
begin
|
1086
|
+
t.call
|
1087
|
+
rescue
|
1088
|
+
EventMachine.handle_runtime_error
|
1089
|
+
end
|
1031
1090
|
elsif opcode == ConnectionCompleted
|
1032
1091
|
c = @conns[conn_binding] or raise ConnectionNotBound
|
1033
|
-
|
1092
|
+
begin
|
1093
|
+
c.connection_completed
|
1094
|
+
rescue
|
1095
|
+
EventMachine.handle_runtime_error
|
1096
|
+
end
|
1034
1097
|
elsif opcode == LoopbreakSignalled
|
1098
|
+
begin
|
1035
1099
|
run_deferred_callbacks
|
1100
|
+
rescue
|
1101
|
+
EventMachine.handle_runtime_error
|
1102
|
+
end
|
1036
1103
|
end
|
1037
1104
|
end
|
1038
1105
|
|
1039
1106
|
|
1107
|
+
# Default handler for RuntimeErrors that are raised in user code.
|
1108
|
+
# The default behavior is to re-raise the error, which ends your program.
|
1109
|
+
# To override the default behavior, re-implement this method in your code.
|
1110
|
+
# For example:
|
1111
|
+
#
|
1112
|
+
# module EventMachine
|
1113
|
+
# def self.handle_runtime_error
|
1114
|
+
# $>.puts $!
|
1115
|
+
# end
|
1116
|
+
# end
|
1117
|
+
#
|
1118
|
+
#--
|
1119
|
+
# We need to ensure that any code path which invokes user code rescues RuntimeError
|
1120
|
+
# and calls this method. The obvious place to do that is in #event_callback,
|
1121
|
+
# but, scurrilously, it turns out that we need to be finer grained that that.
|
1122
|
+
# Periodic timers, in particular, wrap their invocations of user code inside
|
1123
|
+
# procs that do other stuff we can't not do, like schedule the next invocation.
|
1124
|
+
# This is a potential non-robustness, since we need to remember to hook in the
|
1125
|
+
# error handler whenever and wherever we change how user code is invoked.
|
1126
|
+
#
|
1127
|
+
def EventMachine::handle_runtime_error
|
1128
|
+
@runtime_error_hook ? @runtime_error_hook.call : raise
|
1129
|
+
end
|
1130
|
+
|
1131
|
+
# Sets a handler for RuntimeErrors that are raised in user code.
|
1132
|
+
# Pass a block with no parameters. You can also call this method without a block,
|
1133
|
+
# which restores the default behavior (see #handle_runtime_error).
|
1134
|
+
#
|
1135
|
+
def EventMachine::set_runtime_error_hook &blk
|
1136
|
+
@runtime_error_hook = blk
|
1137
|
+
end
|
1138
|
+
|
1040
1139
|
# Documentation stub
|
1041
1140
|
#--
|
1042
1141
|
# This is a provisional implementation of a stream-oriented file access object.
|
@@ -1083,14 +1182,33 @@ module EventMachine
|
|
1083
1182
|
# only by user code.
|
1084
1183
|
#
|
1085
1184
|
class Connection
|
1086
|
-
|
1087
1185
|
# EXPERIMENTAL. Added the reconnect methods, which may go away.
|
1088
1186
|
attr_accessor :signature
|
1089
1187
|
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1188
|
+
# Override .new so subclasses don't have to call super and can ignore
|
1189
|
+
# connection-specific arguments
|
1190
|
+
#
|
1191
|
+
def self.new sig, *args #:nodoc:
|
1192
|
+
allocate.instance_eval do
|
1193
|
+
# Call a superclass's #initialize if it has one
|
1194
|
+
initialize *args
|
1195
|
+
|
1196
|
+
# Store signature and run #post_init
|
1197
|
+
@signature = sig
|
1198
|
+
begin
|
1199
|
+
post_init
|
1200
|
+
rescue
|
1201
|
+
EventMachine::handle_runtime_error
|
1202
|
+
end
|
1203
|
+
|
1204
|
+
self
|
1205
|
+
end
|
1206
|
+
end
|
1207
|
+
|
1208
|
+
# Stubbed initialize so legacy superclasses can safely call super
|
1209
|
+
#
|
1210
|
+
def initialize(*args) #:nodoc:
|
1211
|
+
end
|
1094
1212
|
|
1095
1213
|
# EventMachine::Connection#post_init is called by the event loop
|
1096
1214
|
# immediately after the network connection has been established,
|
@@ -1207,6 +1325,17 @@ class Connection
|
|
1207
1325
|
EventMachine::send_data @signature, data, data.length
|
1208
1326
|
end
|
1209
1327
|
|
1328
|
+
# Returns true if the connection is in an error state, false otherwise.
|
1329
|
+
# In general, you can detect the occurrence of communication errors or unexpected
|
1330
|
+
# disconnection by the remote peer by handing the #unbind method. In some cases, however,
|
1331
|
+
# it's useful to check the status of the connection using #error? before attempting to send data.
|
1332
|
+
# This function is synchronous: it will return immediately without blocking.
|
1333
|
+
#
|
1334
|
+
#
|
1335
|
+
def error?
|
1336
|
+
EventMachine::report_connection_error_status(@signature) != 0
|
1337
|
+
end
|
1338
|
+
|
1210
1339
|
# #connection_completed is called by the event loop when a remote TCP connection
|
1211
1340
|
# attempt completes successfully. You can expect to get this notification after calls
|
1212
1341
|
# to EventMachine#connect. Remember that EventMachine makes remote connections
|
@@ -1273,10 +1402,13 @@ class Connection
|
|
1273
1402
|
# but to be really safe, send messages smaller than the Ethernet-packet
|
1274
1403
|
# size (typically about 1400 bytes). Some very restrictive WANs
|
1275
1404
|
# will either drop or truncate packets larger than about 500 bytes.
|
1405
|
+
#--
|
1406
|
+
# Added the Integer wrapper around the port parameter per suggestion by
|
1407
|
+
# Matthieu Riou, after he passed a String and spent hours tearing his hair out.
|
1276
1408
|
#
|
1277
1409
|
def send_datagram data, recipient_address, recipient_port
|
1278
1410
|
data = data.to_s
|
1279
|
-
EventMachine::send_datagram @signature, data, data.length, recipient_address, recipient_port
|
1411
|
+
EventMachine::send_datagram @signature, data, data.length, recipient_address, Integer(recipient_port)
|
1280
1412
|
end
|
1281
1413
|
|
1282
1414
|
|
@@ -1298,6 +1430,13 @@ class Connection
|
|
1298
1430
|
EventMachine::get_subprocess_pid @signature
|
1299
1431
|
end
|
1300
1432
|
|
1433
|
+
# Returns a subprocess exit status. Only useful for #popen. Call it in your
|
1434
|
+
# #unbind handler.
|
1435
|
+
#
|
1436
|
+
def get_status
|
1437
|
+
EventMachine::get_subprocess_status @signature
|
1438
|
+
end
|
1439
|
+
|
1301
1440
|
# comm_inactivity_timeout returns the current value (in seconds) of the inactivity-timeout
|
1302
1441
|
# property of network-connection and datagram-socket objects. A nonzero value
|
1303
1442
|
# indicates that the connection or socket will automatically be closed if no read or write
|
@@ -1373,7 +1512,11 @@ class Connection
|
|
1373
1512
|
EventMachine::add_timer @interval, proc {self.fire}
|
1374
1513
|
end
|
1375
1514
|
def fire
|
1376
|
-
|
1515
|
+
begin
|
1516
|
+
@code.call
|
1517
|
+
rescue
|
1518
|
+
EventMachine::handle_runtime_error
|
1519
|
+
end
|
1377
1520
|
schedule unless @cancelled
|
1378
1521
|
end
|
1379
1522
|
def cancel
|
@@ -1398,6 +1541,10 @@ class Connection
|
|
1398
1541
|
|
1399
1542
|
end
|
1400
1543
|
|
1544
|
+
module Protocols
|
1545
|
+
# In this module, we define standard protocol implementations.
|
1546
|
+
# They get included from separate source files.
|
1547
|
+
end
|
1401
1548
|
|
1402
1549
|
end # module EventMachine
|
1403
1550
|
|
@@ -1405,6 +1552,7 @@ end # module EventMachine
|
|
1405
1552
|
|
1406
1553
|
# Save everyone some typing.
|
1407
1554
|
EM = EventMachine
|
1555
|
+
EM::P = EventMachine::Protocols
|
1408
1556
|
|
1409
1557
|
|
1410
1558
|
# At the bottom of this module, we load up protocol handlers that depend on some
|
@@ -1417,7 +1565,11 @@ require 'protocols/httpclient'
|
|
1417
1565
|
require 'protocols/line_and_text'
|
1418
1566
|
require 'protocols/header_and_content'
|
1419
1567
|
require 'protocols/linetext2'
|
1568
|
+
require 'protocols/httpcli2'
|
1420
1569
|
require 'protocols/stomp'
|
1421
1570
|
require 'protocols/smtpclient'
|
1422
1571
|
require 'protocols/smtpserver'
|
1572
|
+
require 'protocols/saslauth'
|
1573
|
+
|
1574
|
+
|
1423
1575
|
|