libc-eventmachine 0.12.5.42 → 0.12.7.42
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +13 -0
- data/README +3 -0
- data/Rakefile +60 -1
- data/eventmachine.gemspec +32 -0
- data/ext/cmain.cpp +4 -0
- data/ext/cplusplus.cpp +16 -0
- data/ext/em.cpp +6 -2
- data/ext/rubymain.cpp +12 -9
- data/java/.classpath +8 -0
- data/java/.project +17 -0
- data/lib/em/processes.rb +45 -0
- data/lib/eventmachine.rb +108 -98
- data/lib/eventmachine_version.rb +1 -1
- data/lib/pr_eventmachine.rb +1 -1
- data/setup.rb +1585 -0
- data/tests/test_connection_count.rb +24 -14
- data/tests/test_error_handler.rb +7 -4
- data/tests/test_errors.rb +2 -2
- data/tests/test_processes.rb +39 -0
- data/web/whatis +7 -0
- metadata +87 -109
data/.gitignore
ADDED
data/README
ADDED
data/Rakefile
CHANGED
@@ -90,7 +90,7 @@ Spec = Gem::Specification.new do |s|
|
|
90
90
|
s.rdoc_options = %w(--title EventMachine --main docs/README --line-numbers)
|
91
91
|
s.extra_rdoc_files = Dir['docs/*']
|
92
92
|
|
93
|
-
s.files =
|
93
|
+
s.files = `git ls-files`.split("\n")
|
94
94
|
|
95
95
|
s.require_path = 'lib'
|
96
96
|
|
@@ -128,6 +128,65 @@ using TCP/IP, especially if custom protocols are required.
|
|
128
128
|
s.version = EventMachine::VERSION
|
129
129
|
end
|
130
130
|
|
131
|
+
if RUBY_PLATFORM =~ /mswin/
|
132
|
+
Spec.platform = 'x86-mswin32-60'
|
133
|
+
Spec.files += %w[ lib/rubyeventmachine.so lib/fastfilereaderext.so ]
|
134
|
+
Spec.extensions = nil
|
135
|
+
end
|
136
|
+
|
137
|
+
# this is a hack right now, it requires installing msysgit in the global path so it can use tar/curl/etc.
|
138
|
+
namespace :win32 do
|
139
|
+
task :check_git do
|
140
|
+
unless `git` =~ /rebase/
|
141
|
+
raise 'git not found, install msys git into the GLOBAL PATH: http://msysgit.googlecode.com/files/Git-1.6.2-preview20090308.exe'
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
task :check_vc6 do
|
146
|
+
begin
|
147
|
+
raise unless `nmake 2>&1` =~ /Microsoft/
|
148
|
+
rescue
|
149
|
+
raise 'VC6 not found, please run c:\vc\setvc.bat vc6'
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
task :check_perl do
|
154
|
+
unless `perl --version` =~ /ActiveState/
|
155
|
+
raise 'ActiveState perl required to build OpenSSL: http://downloads.activestate.com/ActivePerl/Windows/5.10/ActivePerl-5.10.0.1004-MSWin32-x86-287188.msi'
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
task :build_openssl => [:check_git, :check_perl, :check_vc6] do
|
160
|
+
mkdir_p 'build'
|
161
|
+
chdir 'build' do
|
162
|
+
unless File.exists?('openssl-0.9.8j')
|
163
|
+
sh 'curl http://www.openssl.org/source/openssl-0.9.8j.tar.gz > openssl.tar.gz'
|
164
|
+
sh 'tar zxvf openssl.tar.gz' rescue nil # fails because of symlinks
|
165
|
+
end
|
166
|
+
|
167
|
+
mkdir_p 'local'
|
168
|
+
chdir 'openssl-0.9.8j' do
|
169
|
+
sh "perl Configure VC-WIN32 --prefix=\"../local/\""
|
170
|
+
sh 'ms\do_ms.bat'
|
171
|
+
sh 'nmake -f ms\nt.mak install'
|
172
|
+
end
|
173
|
+
|
174
|
+
chdir '../ext' do
|
175
|
+
sh 'git clean -fd .'
|
176
|
+
end
|
177
|
+
|
178
|
+
mv 'local/include/openssl', '../ext/'
|
179
|
+
mv 'local/lib/ssleay32.lib', '../ext/'
|
180
|
+
mv 'local/lib/libeay32.lib', '../ext/'
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
task :gem => :build_openssl do
|
185
|
+
Rake::Task['build'].invoke
|
186
|
+
Rake::Task['gem'].invoke
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
131
190
|
namespace :ext do
|
132
191
|
ext_sources = FileList['ext/*.{h,cpp,rb,c}']
|
133
192
|
ffr_sources = FileList['ext/fastfilereader/*.{h,cpp,rb}']
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{eventmachine}
|
5
|
+
s.version = "0.12.7.42"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Francis Cianfrocca"]
|
9
|
+
s.date = %q{2009-03-10}
|
10
|
+
s.description = %q{EventMachine implements a fast, single-threaded engine for arbitrary network communications. It's extremely easy to use in Ruby. EventMachine wraps all interactions with IP sockets, allowing programs to concentrate on the implementation of network protocols. It can be used to create both network servers and clients. To create a server or client, a Ruby program only needs to specify the IP address and port, and provide a Module that implements the communications protocol. Implementations of several standard network protocols are provided with the package, primarily to serve as examples. The real goal of EventMachine is to enable programs to easily interface with other programs using TCP/IP, especially if custom protocols are required.}
|
11
|
+
s.email = %q{garbagecat10@gmail.com}
|
12
|
+
s.extensions = ["ext/extconf.rb", "ext/fastfilereader/extconf.rb"]
|
13
|
+
s.extra_rdoc_files = ["docs/COPYING", "docs/ChangeLog", "docs/DEFERRABLES", "docs/EPOLL", "docs/GNU", "docs/INSTALL", "docs/KEYBOARD", "docs/LEGAL", "docs/LIGHTWEIGHT_CONCURRENCY", "docs/PURE_RUBY", "docs/README", "docs/RELEASE_NOTES", "docs/SMTP", "docs/SPAWNED_PROCESSES", "docs/TODO"]
|
14
|
+
s.files = [".gitignore", "README", "Rakefile", "docs/COPYING", "docs/ChangeLog", "docs/DEFERRABLES", "docs/EPOLL", "docs/GNU", "docs/INSTALL", "docs/KEYBOARD", "docs/LEGAL", "docs/LIGHTWEIGHT_CONCURRENCY", "docs/PURE_RUBY", "docs/README", "docs/RELEASE_NOTES", "docs/SMTP", "docs/SPAWNED_PROCESSES", "docs/TODO", "eventmachine.gemspec", "ext/binder.cpp", "ext/binder.h", "ext/cmain.cpp", "ext/cplusplus.cpp", "ext/ed.cpp", "ext/ed.h", "ext/em.cpp", "ext/em.h", "ext/emwin.cpp", "ext/emwin.h", "ext/epoll.cpp", "ext/epoll.h", "ext/eventmachine.h", "ext/eventmachine_cpp.h", "ext/extconf.rb", "ext/fastfilereader/extconf.rb", "ext/fastfilereader/mapper.cpp", "ext/fastfilereader/mapper.h", "ext/fastfilereader/rubymain.cpp", "ext/files.cpp", "ext/files.h", "ext/kb.cpp", "ext/page.cpp", "ext/page.h", "ext/pipe.cpp", "ext/project.h", "ext/rubymain.cpp", "ext/sigs.cpp", "ext/sigs.h", "ext/ssl.cpp", "ext/ssl.h", "java/.classpath", "java/.project", "java/src/com/rubyeventmachine/Application.java", "java/src/com/rubyeventmachine/Connection.java", "java/src/com/rubyeventmachine/ConnectionFactory.java", "java/src/com/rubyeventmachine/DefaultConnectionFactory.java", "java/src/com/rubyeventmachine/EmReactor.java", "java/src/com/rubyeventmachine/EmReactorException.java", "java/src/com/rubyeventmachine/EventableChannel.java", "java/src/com/rubyeventmachine/EventableDatagramChannel.java", "java/src/com/rubyeventmachine/EventableSocketChannel.java", "java/src/com/rubyeventmachine/PeriodicTimer.java", "java/src/com/rubyeventmachine/Timer.java", "java/src/com/rubyeventmachine/tests/ApplicationTest.java", "java/src/com/rubyeventmachine/tests/ConnectTest.java", "java/src/com/rubyeventmachine/tests/EMTest.java", "java/src/com/rubyeventmachine/tests/TestDatagrams.java", "java/src/com/rubyeventmachine/tests/TestServers.java", "java/src/com/rubyeventmachine/tests/TestTimers.java", "lib/em/deferrable.rb", "lib/em/eventable.rb", "lib/em/future.rb", "lib/em/messages.rb", "lib/em/processes.rb", "lib/em/spawnable.rb", "lib/em/streamer.rb", "lib/eventmachine.rb", "lib/eventmachine_version.rb", "lib/evma.rb", "lib/evma/callback.rb", "lib/evma/container.rb", "lib/evma/factory.rb", "lib/evma/protocol.rb", "lib/evma/reactor.rb", "lib/jeventmachine.rb", "lib/pr_eventmachine.rb", "lib/protocols/buftok.rb", "lib/protocols/header_and_content.rb", "lib/protocols/httpcli2.rb", "lib/protocols/httpclient.rb", "lib/protocols/line_and_text.rb", "lib/protocols/linetext2.rb", "lib/protocols/memcache.rb", "lib/protocols/postgres.rb", "lib/protocols/saslauth.rb", "lib/protocols/smtpclient.rb", "lib/protocols/smtpserver.rb", "lib/protocols/stomp.rb", "lib/protocols/tcptest.rb", "setup.rb", "tasks/cpp.rake", "tasks/project.rake", "tasks/tests.rake", "tests/test_attach.rb", "tests/test_basic.rb", "tests/test_bind.rb", "tests/test_connection_count.rb", "tests/test_defer.rb", "tests/test_epoll.rb", "tests/test_error_handler.rb", "tests/test_errors.rb", "tests/test_eventables.rb", "tests/test_exc.rb", "tests/test_futures.rb", "tests/test_handler_check.rb", "tests/test_hc.rb", "tests/test_httpclient.rb", "tests/test_httpclient2.rb", "tests/test_kb.rb", "tests/test_ltp.rb", "tests/test_ltp2.rb", "tests/test_next_tick.rb", "tests/test_processes.rb", "tests/test_pure.rb", "tests/test_running.rb", "tests/test_sasl.rb", "tests/test_send_file.rb", "tests/test_servers.rb", "tests/test_smtpclient.rb", "tests/test_smtpserver.rb", "tests/test_spawn.rb", "tests/test_ssl_args.rb", "tests/test_ssl_methods.rb", "tests/test_timers.rb", "tests/test_ud.rb", "tests/testem.rb", "web/whatis"]
|
15
|
+
s.has_rdoc = true
|
16
|
+
s.homepage = %q{http://rubyeventmachine.com}
|
17
|
+
s.rdoc_options = ["--title", "EventMachine", "--main", "docs/README", "--line-numbers"]
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
s.rubyforge_project = %q{eventmachine}
|
20
|
+
s.rubygems_version = %q{1.3.1}
|
21
|
+
s.summary = %q{Ruby/EventMachine library}
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
25
|
+
s.specification_version = 2
|
26
|
+
|
27
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
28
|
+
else
|
29
|
+
end
|
30
|
+
else
|
31
|
+
end
|
32
|
+
end
|
data/ext/cmain.cpp
CHANGED
@@ -324,6 +324,7 @@ evma_get_subprocess_pid
|
|
324
324
|
extern "C" int evma_get_subprocess_pid (const char *binding, pid_t *pid)
|
325
325
|
{
|
326
326
|
ensure_eventmachine("evma_get_subprocess_pid");
|
327
|
+
#ifdef OS_UNIX
|
327
328
|
PipeDescriptor *pd = dynamic_cast <PipeDescriptor*> (Bindable_t::GetObject (binding));
|
328
329
|
if (pd) {
|
329
330
|
return pd->GetSubprocessPid (pid) ? 1 : 0;
|
@@ -334,6 +335,9 @@ extern "C" int evma_get_subprocess_pid (const char *binding, pid_t *pid)
|
|
334
335
|
}
|
335
336
|
else
|
336
337
|
return 0;
|
338
|
+
#else
|
339
|
+
return 0;
|
340
|
+
#endif
|
337
341
|
}
|
338
342
|
|
339
343
|
/**************************
|
data/ext/cplusplus.cpp
CHANGED
@@ -49,7 +49,11 @@ void EM::AddTimer (int milliseconds, void (*func)())
|
|
49
49
|
{
|
50
50
|
if (func) {
|
51
51
|
const char *sig = evma_install_oneshot_timer (milliseconds);
|
52
|
+
#ifdef OS_SOLARIS8
|
53
|
+
Timers.insert (map<string, void(*)()>::value_type (sig, func));
|
54
|
+
#else
|
52
55
|
Timers.insert (make_pair (sig, func));
|
56
|
+
#endif
|
53
57
|
}
|
54
58
|
}
|
55
59
|
|
@@ -72,7 +76,11 @@ void EM::Acceptor::Accept (const char *signature)
|
|
72
76
|
{
|
73
77
|
Connection *c = MakeConnection();
|
74
78
|
c->Signature = signature;
|
79
|
+
#ifdef OS_SOLARIS8
|
80
|
+
Eventables.insert (std::map<std::string,EM::Eventable*>::value_type (c->Signature, c));
|
81
|
+
#else
|
75
82
|
Eventables.insert (make_pair (c->Signature, c));
|
83
|
+
#endif
|
76
84
|
c->PostInit();
|
77
85
|
}
|
78
86
|
|
@@ -114,7 +122,11 @@ EM::Connection::Connect
|
|
114
122
|
void EM::Connection::Connect (const char *host, int port, const char * bind_host)
|
115
123
|
{
|
116
124
|
Signature = evma_connect_to_server (host, port, bind_host);
|
125
|
+
#ifdef OS_SOLARIS8
|
126
|
+
Eventables.insert( std::map<std::string,EM::Eventable*>::value_type (Signature, this));
|
127
|
+
#else
|
117
128
|
Eventables.insert( make_pair (Signature, this));
|
129
|
+
#endif
|
118
130
|
}
|
119
131
|
|
120
132
|
/*******************
|
@@ -124,7 +136,11 @@ EM::Acceptor::Start
|
|
124
136
|
void EM::Acceptor::Start (const char *host, int port)
|
125
137
|
{
|
126
138
|
Signature = evma_create_tcp_server (host, port);
|
139
|
+
#ifdef OS_SOLARIS8
|
140
|
+
Eventables.insert( std::map<std::string,EM::Eventable*>::value_type (Signature, this));
|
141
|
+
#else
|
127
142
|
Eventables.insert( make_pair (Signature, this));
|
143
|
+
#endif
|
128
144
|
}
|
129
145
|
|
130
146
|
|
data/ext/em.cpp
CHANGED
@@ -86,6 +86,7 @@ EventMachine_t::EventMachine_t (void (*event_callback)(const char*, int, const c
|
|
86
86
|
LoopBreakerWriter (-1),
|
87
87
|
bEpoll (false),
|
88
88
|
bKqueue (false),
|
89
|
+
kqfd (-1),
|
89
90
|
epfd (-1)
|
90
91
|
{
|
91
92
|
// Default time-slice is just smaller than one hundred mills.
|
@@ -932,8 +933,11 @@ const char *EventMachine_t::InstallOneshotTimer (int milliseconds)
|
|
932
933
|
#endif
|
933
934
|
|
934
935
|
Timer_t t;
|
935
|
-
|
936
|
-
|
936
|
+
#ifdef OS_SOLARIS8
|
937
|
+
multimap<Int64,Timer_t>::iterator i = Timers.insert (multimap<Int64,Timer_t>::value_type (fire_at, t));
|
938
|
+
#else
|
939
|
+
multimap<Int64,Timer_t>::iterator i = Timers.insert (make_pair (fire_at, t));
|
940
|
+
#endif
|
937
941
|
return i->second.GetBindingChars();
|
938
942
|
}
|
939
943
|
|
data/ext/rubymain.cpp
CHANGED
@@ -30,6 +30,9 @@ Statics
|
|
30
30
|
static VALUE EmModule;
|
31
31
|
static VALUE EmConnection;
|
32
32
|
|
33
|
+
static VALUE EM_eUnknownTimerFired;
|
34
|
+
static VALUE EM_eConnectionNotBound;
|
35
|
+
|
33
36
|
static VALUE Intern_at_signature;
|
34
37
|
static VALUE Intern_at_timers;
|
35
38
|
static VALUE Intern_at_conns;
|
@@ -67,21 +70,21 @@ static void event_callback (struct em_event* e)
|
|
67
70
|
VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
|
68
71
|
VALUE q = rb_hash_aref (t, rb_str_new2(a1));
|
69
72
|
if (q == Qnil)
|
70
|
-
rb_raise (
|
73
|
+
rb_raise (EM_eConnectionNotBound, "received %d bytes of data for unknown signature: %s", a4, a1);
|
71
74
|
rb_funcall (q, Intern_receive_data, 1, rb_str_new (a3, a4));
|
72
75
|
}
|
73
76
|
else if (a2 == EM_CONNECTION_NOTIFY_READABLE) {
|
74
77
|
VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
|
75
78
|
VALUE q = rb_hash_aref (t, rb_str_new2(a1));
|
76
79
|
if (q == Qnil)
|
77
|
-
rb_raise (
|
80
|
+
rb_raise (EM_eConnectionNotBound, "unknown connection: %s", a1);
|
78
81
|
rb_funcall (q, Intern_notify_readable, 0);
|
79
82
|
}
|
80
83
|
else if (a2 == EM_CONNECTION_NOTIFY_WRITABLE) {
|
81
84
|
VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
|
82
85
|
VALUE q = rb_hash_aref (t, rb_str_new2(a1));
|
83
86
|
if (q == Qnil)
|
84
|
-
rb_raise (
|
87
|
+
rb_raise (EM_eConnectionNotBound, "unknown connection: %s", a1);
|
85
88
|
rb_funcall (q, Intern_notify_writable, 0);
|
86
89
|
}
|
87
90
|
else if (a2 == EM_LOOPBREAK_SIGNAL) {
|
@@ -91,14 +94,14 @@ static void event_callback (struct em_event* e)
|
|
91
94
|
VALUE t = rb_ivar_get (EmModule, Intern_at_timers);
|
92
95
|
VALUE q = rb_funcall (t, Intern_delete, 1, rb_str_new(a3, a4));
|
93
96
|
if (q == Qnil)
|
94
|
-
rb_raise (
|
97
|
+
rb_raise (EM_eUnknownTimerFired, "no such timer: %s", a1);
|
95
98
|
rb_funcall (q, Intern_call, 0);
|
96
99
|
}
|
97
100
|
else if (a2 == EM_SSL_HANDSHAKE_COMPLETED) {
|
98
101
|
VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
|
99
102
|
VALUE q = rb_hash_aref (t, rb_str_new2(a1));
|
100
103
|
if (q == Qnil)
|
101
|
-
rb_raise (
|
104
|
+
rb_raise (EM_eConnectionNotBound, "unknown connection: %s", a1);
|
102
105
|
rb_funcall (q, Intern_ssl_handshake_completed, 0);
|
103
106
|
}
|
104
107
|
else
|
@@ -109,7 +112,7 @@ static void event_callback (struct em_event* e)
|
|
109
112
|
event_error_handler
|
110
113
|
*******************/
|
111
114
|
|
112
|
-
static void event_error_handler(
|
115
|
+
static void event_error_handler(VALUE unused, VALUE err)
|
113
116
|
{
|
114
117
|
VALUE error_handler = rb_ivar_get(EmModule, Intern_at_error_handler);
|
115
118
|
rb_funcall (error_handler, Intern_call, 1, err);
|
@@ -130,7 +133,7 @@ static void event_callback_wrapper (const char *a1, int a2, const char *a3, int
|
|
130
133
|
if (!rb_ivar_defined(EmModule, Intern_at_error_handler))
|
131
134
|
event_callback(&e);
|
132
135
|
else
|
133
|
-
rb_rescue((VALUE (*)(ANYARGS))event_callback, (VALUE)&e, (VALUE (*)(ANYARGS))event_error_handler,
|
136
|
+
rb_rescue((VALUE (*)(ANYARGS))event_callback, (VALUE)&e, (VALUE (*)(ANYARGS))event_error_handler, Qnil);
|
134
137
|
}
|
135
138
|
|
136
139
|
/**************************
|
@@ -779,9 +782,9 @@ extern "C" void Init_rubyeventmachine()
|
|
779
782
|
EmModule = rb_define_module ("EventMachine");
|
780
783
|
EmConnection = rb_define_class_under (EmModule, "Connection", rb_cObject);
|
781
784
|
|
782
|
-
rb_define_class_under (EmModule, "ConnectionNotBound", rb_eException);
|
783
785
|
rb_define_class_under (EmModule, "NoHandlerForAcceptedConnection", rb_eException);
|
784
|
-
rb_define_class_under (EmModule, "
|
786
|
+
EM_eConnectionNotBound = rb_define_class_under (EmModule, "ConnectionNotBound", rb_eRuntimeError);
|
787
|
+
EM_eUnknownTimerFired = rb_define_class_under (EmModule, "UnknownTimerFired", rb_eRuntimeError);
|
785
788
|
|
786
789
|
rb_define_module_function (EmModule, "initialize_event_machine", (VALUE(*)(...))t_initialize_event_machine, 0);
|
787
790
|
rb_define_module_function (EmModule, "run_machine", (VALUE(*)(...))t_run_machine_without_threads, 0);
|
data/java/.classpath
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<classpath>
|
3
|
+
<classpathentry kind="src" path="src"/>
|
4
|
+
<classpathentry excluding="src/" kind="src" path=""/>
|
5
|
+
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
6
|
+
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
|
7
|
+
<classpathentry kind="output" path="src"/>
|
8
|
+
</classpath>
|
data/java/.project
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<projectDescription>
|
3
|
+
<name>em_reactor</name>
|
4
|
+
<comment></comment>
|
5
|
+
<projects>
|
6
|
+
</projects>
|
7
|
+
<buildSpec>
|
8
|
+
<buildCommand>
|
9
|
+
<name>org.eclipse.jdt.core.javabuilder</name>
|
10
|
+
<arguments>
|
11
|
+
</arguments>
|
12
|
+
</buildCommand>
|
13
|
+
</buildSpec>
|
14
|
+
<natures>
|
15
|
+
<nature>org.eclipse.jdt.core.javanature</nature>
|
16
|
+
</natures>
|
17
|
+
</projectDescription>
|
data/lib/em/processes.rb
CHANGED
@@ -63,6 +63,51 @@ module EventMachine
|
|
63
63
|
succeed( @data.join )
|
64
64
|
end
|
65
65
|
end
|
66
|
+
|
67
|
+
class SystemCmd < EventMachine::Connection # :nodoc:
|
68
|
+
def initialize cb
|
69
|
+
@cb = cb
|
70
|
+
@output = []
|
71
|
+
end
|
72
|
+
def receive_data data
|
73
|
+
@output << data
|
74
|
+
end
|
75
|
+
def unbind
|
76
|
+
@cb.call @output.join(''), get_status if @cb
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# EM::system is a simple wrapper for EM::popen. It is similar to Kernel::system, but requires a
|
81
|
+
# single string argument for the command and performs no shell expansion.
|
82
|
+
#
|
83
|
+
# The block or proc passed to EM::system is called with two arguments: the output generated by the command,
|
84
|
+
# and a Process::Status that contains information about the command's execution.
|
85
|
+
#
|
86
|
+
# EM.run{
|
87
|
+
# EM.system('ls'){ |output,status| puts output if status.exitstatus == 0 }
|
88
|
+
# }
|
89
|
+
#
|
90
|
+
# You can also supply an additional proc to send some data to the process:
|
91
|
+
#
|
92
|
+
# EM.run{
|
93
|
+
# EM.system('sh', proc{ |process|
|
94
|
+
# process.send_data("echo hello\n")
|
95
|
+
# process.send_data("exit\n")
|
96
|
+
# }, proc{ |out,status|
|
97
|
+
# puts(out)
|
98
|
+
# })
|
99
|
+
# }
|
100
|
+
#
|
101
|
+
# Like EM::popen, EM::system currently does not work on windows.
|
102
|
+
#
|
103
|
+
def EventMachine::system cmd, *args, &cb
|
104
|
+
cb ||= args.pop if args.last.is_a? Proc
|
105
|
+
init = args.pop if args.last.is_a? Proc
|
106
|
+
|
107
|
+
EM.popen(cmd, SystemCmd, cb) do |c|
|
108
|
+
init[c] if init
|
109
|
+
end
|
110
|
+
end
|
66
111
|
end
|
67
112
|
|
68
113
|
|
data/lib/eventmachine.rb
CHANGED
@@ -538,6 +538,8 @@ module EventMachine
|
|
538
538
|
begin
|
539
539
|
port = Integer(port)
|
540
540
|
rescue ArgumentError, TypeError
|
541
|
+
# there was no port, so server must be a unix domain socket
|
542
|
+
# the port argument is actually the handler, and the handler is one of the args
|
541
543
|
args.unshift handler if handler
|
542
544
|
handler = port
|
543
545
|
port = nil
|
@@ -684,6 +686,8 @@ module EventMachine
|
|
684
686
|
begin
|
685
687
|
port = Integer(port)
|
686
688
|
rescue ArgumentError, TypeError
|
689
|
+
# there was no port, so server must be a unix domain socket
|
690
|
+
# the port argument is actually the handler, and the handler is one of the args
|
687
691
|
args.unshift handler if handler
|
688
692
|
handler = port
|
689
693
|
port = nil
|
@@ -1250,10 +1254,7 @@ module EventMachine
|
|
1250
1254
|
# runs down open connections). It should go on the other calls to user
|
1251
1255
|
# code, but the performance impact may be too large.
|
1252
1256
|
#
|
1253
|
-
if opcode ==
|
1254
|
-
c = @conns[conn_binding] or raise ConnectionNotBound, "received data #{data} for unknown signature: #{conn_binding}"
|
1255
|
-
c.receive_data data
|
1256
|
-
elsif opcode == ConnectionUnbound
|
1257
|
+
if opcode == ConnectionUnbound
|
1257
1258
|
if c = @conns.delete( conn_binding )
|
1258
1259
|
begin
|
1259
1260
|
c.unbind
|
@@ -1273,12 +1274,17 @@ module EventMachine
|
|
1273
1274
|
@conns[data] = c
|
1274
1275
|
blk and blk.call(c)
|
1275
1276
|
c # (needed?)
|
1276
|
-
elsif opcode == TimerFired
|
1277
|
-
t = @timers.delete( data ) or raise UnknownTimerFired, "timer data: #{data}"
|
1278
|
-
t.call
|
1279
1277
|
elsif opcode == ConnectionCompleted
|
1280
1278
|
c = @conns[conn_binding] or raise ConnectionNotBound, "received ConnectionCompleted for unknown signature: #{conn_binding}"
|
1281
1279
|
c.connection_completed
|
1280
|
+
##
|
1281
|
+
# The remaining code is a fallback for the pure ruby reactor. Usually these events are handled in the C event_callback() in rubymain.cpp
|
1282
|
+
elsif opcode == TimerFired
|
1283
|
+
t = @timers.delete( data ) or raise UnknownTimerFired, "timer data: #{data}"
|
1284
|
+
t.call
|
1285
|
+
elsif opcode == ConnectionData
|
1286
|
+
c = @conns[conn_binding] or raise ConnectionNotBound, "received data #{data} for unknown signature: #{conn_binding}"
|
1287
|
+
c.receive_data data
|
1282
1288
|
elsif opcode == LoopbreakSignalled
|
1283
1289
|
run_deferred_callbacks
|
1284
1290
|
elsif opcode == ConnectionNotifyReadable
|
@@ -1290,98 +1296,102 @@ module EventMachine
|
|
1290
1296
|
end
|
1291
1297
|
end
|
1292
1298
|
|
1293
|
-
private
|
1294
|
-
def EventMachine::original_event_callback conn_binding, opcode, data
|
1295
|
-
#
|
1296
|
-
# Added 03Oct07: Any code path that invokes user-written code must
|
1297
|
-
# wrap itself in a begin/rescue for RuntimeErrors, that calls the
|
1298
|
-
# user-overridable class method #handle_runtime_error.
|
1299
|
-
#
|
1300
|
-
if opcode == ConnectionData
|
1301
|
-
c = @conns[conn_binding] or raise ConnectionNotBound
|
1302
|
-
begin
|
1303
|
-
c.receive_data data
|
1304
|
-
rescue
|
1305
|
-
EventMachine.handle_runtime_error
|
1306
|
-
end
|
1307
|
-
elsif opcode == ConnectionUnbound
|
1308
|
-
if c = @conns.delete( conn_binding )
|
1309
|
-
begin
|
1310
|
-
c.unbind
|
1311
|
-
rescue
|
1312
|
-
EventMachine.handle_runtime_error
|
1313
|
-
end
|
1314
|
-
elsif c = @acceptors.delete( conn_binding )
|
1315
|
-
# no-op
|
1316
|
-
else
|
1317
|
-
raise ConnectionNotBound
|
1318
|
-
end
|
1319
|
-
elsif opcode == ConnectionAccepted
|
1320
|
-
accep,args,blk = @acceptors[conn_binding]
|
1321
|
-
raise NoHandlerForAcceptedConnection unless accep
|
1322
|
-
c = accep.new data, *args
|
1323
|
-
@conns[data] = c
|
1324
|
-
begin
|
1325
|
-
blk and blk.call(c)
|
1326
|
-
rescue
|
1327
|
-
EventMachine.handle_runtime_error
|
1328
|
-
end
|
1329
|
-
c # (needed?)
|
1330
|
-
elsif opcode == TimerFired
|
1331
|
-
t = @timers.delete( data ) or raise UnknownTimerFired
|
1332
|
-
begin
|
1333
|
-
t.call
|
1334
|
-
rescue
|
1335
|
-
EventMachine.handle_runtime_error
|
1336
|
-
end
|
1337
|
-
elsif opcode == ConnectionCompleted
|
1338
|
-
c = @conns[conn_binding] or raise ConnectionNotBound
|
1339
|
-
begin
|
1340
|
-
c.connection_completed
|
1341
|
-
rescue
|
1342
|
-
EventMachine.handle_runtime_error
|
1343
|
-
end
|
1344
|
-
elsif opcode == LoopbreakSignalled
|
1345
|
-
begin
|
1346
|
-
run_deferred_callbacks
|
1347
|
-
rescue
|
1348
|
-
EventMachine.handle_runtime_error
|
1349
|
-
end
|
1350
|
-
end
|
1351
|
-
end
|
1352
|
-
|
1353
|
-
|
1354
|
-
# Default handler for RuntimeErrors that are raised in user code.
|
1355
|
-
# The default behavior is to re-raise the error, which ends your program.
|
1356
|
-
# To override the default behavior, re-implement this method in your code.
|
1357
|
-
# For example:
|
1358
|
-
#
|
1359
|
-
# module EventMachine
|
1360
|
-
# def self.handle_runtime_error
|
1361
|
-
# $>.puts $!
|
1362
|
-
# end
|
1363
|
-
# end
|
1364
|
-
#
|
1365
1299
|
#--
|
1366
|
-
#
|
1367
|
-
#
|
1368
|
-
#
|
1369
|
-
#
|
1370
|
-
#
|
1371
|
-
#
|
1372
|
-
#
|
1373
|
-
#
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
#
|
1379
|
-
#
|
1380
|
-
#
|
1381
|
-
#
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1300
|
+
# The original event_callback below handled runtime errors in ruby and degraded performance significantly.
|
1301
|
+
# An optional C-based error handler is now available via EM::error_handler
|
1302
|
+
#
|
1303
|
+
# private
|
1304
|
+
# def EventMachine::original_event_callback conn_binding, opcode, data
|
1305
|
+
# #
|
1306
|
+
# # Added 03Oct07: Any code path that invokes user-written code must
|
1307
|
+
# # wrap itself in a begin/rescue for RuntimeErrors, that calls the
|
1308
|
+
# # user-overridable class method #handle_runtime_error.
|
1309
|
+
# #
|
1310
|
+
# if opcode == ConnectionData
|
1311
|
+
# c = @conns[conn_binding] or raise ConnectionNotBound
|
1312
|
+
# begin
|
1313
|
+
# c.receive_data data
|
1314
|
+
# rescue
|
1315
|
+
# EventMachine.handle_runtime_error
|
1316
|
+
# end
|
1317
|
+
# elsif opcode == ConnectionUnbound
|
1318
|
+
# if c = @conns.delete( conn_binding )
|
1319
|
+
# begin
|
1320
|
+
# c.unbind
|
1321
|
+
# rescue
|
1322
|
+
# EventMachine.handle_runtime_error
|
1323
|
+
# end
|
1324
|
+
# elsif c = @acceptors.delete( conn_binding )
|
1325
|
+
# # no-op
|
1326
|
+
# else
|
1327
|
+
# raise ConnectionNotBound
|
1328
|
+
# end
|
1329
|
+
# elsif opcode == ConnectionAccepted
|
1330
|
+
# accep,args,blk = @acceptors[conn_binding]
|
1331
|
+
# raise NoHandlerForAcceptedConnection unless accep
|
1332
|
+
# c = accep.new data, *args
|
1333
|
+
# @conns[data] = c
|
1334
|
+
# begin
|
1335
|
+
# blk and blk.call(c)
|
1336
|
+
# rescue
|
1337
|
+
# EventMachine.handle_runtime_error
|
1338
|
+
# end
|
1339
|
+
# c # (needed?)
|
1340
|
+
# elsif opcode == TimerFired
|
1341
|
+
# t = @timers.delete( data ) or raise UnknownTimerFired
|
1342
|
+
# begin
|
1343
|
+
# t.call
|
1344
|
+
# rescue
|
1345
|
+
# EventMachine.handle_runtime_error
|
1346
|
+
# end
|
1347
|
+
# elsif opcode == ConnectionCompleted
|
1348
|
+
# c = @conns[conn_binding] or raise ConnectionNotBound
|
1349
|
+
# begin
|
1350
|
+
# c.connection_completed
|
1351
|
+
# rescue
|
1352
|
+
# EventMachine.handle_runtime_error
|
1353
|
+
# end
|
1354
|
+
# elsif opcode == LoopbreakSignalled
|
1355
|
+
# begin
|
1356
|
+
# run_deferred_callbacks
|
1357
|
+
# rescue
|
1358
|
+
# EventMachine.handle_runtime_error
|
1359
|
+
# end
|
1360
|
+
# end
|
1361
|
+
# end
|
1362
|
+
#
|
1363
|
+
#
|
1364
|
+
# # Default handler for RuntimeErrors that are raised in user code.
|
1365
|
+
# # The default behavior is to re-raise the error, which ends your program.
|
1366
|
+
# # To override the default behavior, re-implement this method in your code.
|
1367
|
+
# # For example:
|
1368
|
+
# #
|
1369
|
+
# # module EventMachine
|
1370
|
+
# # def self.handle_runtime_error
|
1371
|
+
# # $>.puts $!
|
1372
|
+
# # end
|
1373
|
+
# # end
|
1374
|
+
# #
|
1375
|
+
# #--
|
1376
|
+
# # We need to ensure that any code path which invokes user code rescues RuntimeError
|
1377
|
+
# # and calls this method. The obvious place to do that is in #event_callback,
|
1378
|
+
# # but, scurrilously, it turns out that we need to be finer grained that that.
|
1379
|
+
# # Periodic timers, in particular, wrap their invocations of user code inside
|
1380
|
+
# # procs that do other stuff we can't not do, like schedule the next invocation.
|
1381
|
+
# # This is a potential non-robustness, since we need to remember to hook in the
|
1382
|
+
# # error handler whenever and wherever we change how user code is invoked.
|
1383
|
+
# #
|
1384
|
+
# def EventMachine::handle_runtime_error
|
1385
|
+
# @runtime_error_hook ? @runtime_error_hook.call : raise
|
1386
|
+
# end
|
1387
|
+
#
|
1388
|
+
# # Sets a handler for RuntimeErrors that are raised in user code.
|
1389
|
+
# # Pass a block with no parameters. You can also call this method without a block,
|
1390
|
+
# # which restores the default behavior (see #handle_runtime_error).
|
1391
|
+
# #
|
1392
|
+
# def EventMachine::set_runtime_error_hook &blk
|
1393
|
+
# @runtime_error_hook = blk
|
1394
|
+
# end
|
1385
1395
|
|
1386
1396
|
# Documentation stub
|
1387
1397
|
#--
|
data/lib/eventmachine_version.rb
CHANGED
data/lib/pr_eventmachine.rb
CHANGED
@@ -628,7 +628,7 @@ module EventMachine
|
|
628
628
|
end
|
629
629
|
|
630
630
|
def heartbeat
|
631
|
-
if @inactivity_timeout and (@last_activity + @inactivity_timeout) < Reactor.instance.current_loop_time
|
631
|
+
if @inactivity_timeout and @inactivity_timeout > 0 and (@last_activity + @inactivity_timeout) < Reactor.instance.current_loop_time
|
632
632
|
schedule_close true
|
633
633
|
end
|
634
634
|
end
|