eventmachine 0.12.6-x86-mswin32-60 → 0.12.8-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. data/{docs/README → README} +21 -13
  2. data/Rakefile +14 -4
  3. data/docs/DEFERRABLES +0 -5
  4. data/docs/INSTALL +2 -4
  5. data/docs/LEGAL +1 -1
  6. data/docs/LIGHTWEIGHT_CONCURRENCY +0 -2
  7. data/docs/PURE_RUBY +0 -2
  8. data/docs/RELEASE_NOTES +0 -2
  9. data/docs/SMTP +0 -7
  10. data/docs/SPAWNED_PROCESSES +0 -4
  11. data/docs/TODO +0 -2
  12. data/eventmachine.gemspec +41 -32
  13. data/examples/ex_channel.rb +43 -0
  14. data/examples/ex_queue.rb +2 -0
  15. data/examples/helper.rb +2 -0
  16. data/ext/cmain.cpp +685 -586
  17. data/ext/cplusplus.cpp +15 -6
  18. data/ext/ed.cpp +1732 -1522
  19. data/ext/ed.h +407 -380
  20. data/ext/em.cpp +2263 -1937
  21. data/ext/em.h +223 -186
  22. data/ext/eventmachine.h +111 -98
  23. data/ext/eventmachine_cpp.h +1 -0
  24. data/ext/extconf.rb +4 -0
  25. data/ext/kb.cpp +81 -82
  26. data/ext/pipe.cpp +349 -351
  27. data/ext/project.h +21 -0
  28. data/ext/rubymain.cpp +1047 -847
  29. data/ext/ssl.cpp +38 -1
  30. data/ext/ssl.h +5 -1
  31. data/java/src/com/rubyeventmachine/Application.java +7 -3
  32. data/java/src/com/rubyeventmachine/EmReactor.java +16 -1
  33. data/java/src/com/rubyeventmachine/tests/ConnectTest.java +25 -3
  34. data/lib/{protocols → em}/buftok.rb +16 -5
  35. data/lib/em/callback.rb +26 -0
  36. data/lib/em/channel.rb +57 -0
  37. data/lib/em/connection.rb +505 -0
  38. data/lib/em/deferrable.rb +144 -165
  39. data/lib/em/file_watch.rb +54 -0
  40. data/lib/em/future.rb +24 -25
  41. data/lib/em/messages.rb +1 -1
  42. data/lib/em/process_watch.rb +44 -0
  43. data/lib/em/processes.rb +119 -113
  44. data/lib/em/protocols.rb +35 -0
  45. data/lib/em/protocols/header_and_content.rb +138 -0
  46. data/lib/em/protocols/httpclient.rb +263 -0
  47. data/lib/em/protocols/httpclient2.rb +582 -0
  48. data/lib/{protocols → em/protocols}/line_and_text.rb +2 -2
  49. data/lib/em/protocols/linetext2.rb +160 -0
  50. data/lib/{protocols → em/protocols}/memcache.rb +37 -7
  51. data/lib/em/protocols/object_protocol.rb +39 -0
  52. data/lib/em/protocols/postgres3.rb +247 -0
  53. data/lib/em/protocols/saslauth.rb +175 -0
  54. data/lib/em/protocols/smtpclient.rb +331 -0
  55. data/lib/em/protocols/smtpserver.rb +547 -0
  56. data/lib/em/protocols/stomp.rb +200 -0
  57. data/lib/{protocols → em/protocols}/tcptest.rb +21 -25
  58. data/lib/em/queue.rb +61 -0
  59. data/lib/em/spawnable.rb +53 -56
  60. data/lib/em/streamer.rb +92 -74
  61. data/lib/em/timers.rb +55 -0
  62. data/lib/em/version.rb +3 -0
  63. data/lib/eventmachine.rb +1636 -1926
  64. data/lib/evma.rb +1 -1
  65. data/lib/jeventmachine.rb +106 -101
  66. data/lib/pr_eventmachine.rb +47 -36
  67. data/tasks/project.rake +2 -1
  68. data/tests/client.crt +31 -0
  69. data/tests/client.key +51 -0
  70. data/tests/test_attach.rb +18 -0
  71. data/tests/test_basic.rb +285 -231
  72. data/tests/test_channel.rb +63 -0
  73. data/tests/test_connection_count.rb +2 -2
  74. data/tests/test_epoll.rb +162 -163
  75. data/tests/test_errors.rb +36 -36
  76. data/tests/test_exc.rb +22 -25
  77. data/tests/test_file_watch.rb +49 -0
  78. data/tests/test_futures.rb +77 -93
  79. data/tests/test_hc.rb +2 -2
  80. data/tests/test_httpclient.rb +55 -52
  81. data/tests/test_httpclient2.rb +153 -155
  82. data/tests/test_inactivity_timeout.rb +30 -0
  83. data/tests/test_kb.rb +8 -9
  84. data/tests/test_ltp2.rb +274 -277
  85. data/tests/test_next_tick.rb +135 -109
  86. data/tests/test_object_protocol.rb +37 -0
  87. data/tests/test_process_watch.rb +48 -0
  88. data/tests/test_processes.rb +128 -95
  89. data/tests/test_proxy_connection.rb +92 -0
  90. data/tests/test_pure.rb +1 -5
  91. data/tests/test_queue.rb +44 -0
  92. data/tests/test_running.rb +9 -14
  93. data/tests/test_sasl.rb +32 -34
  94. data/tests/test_send_file.rb +175 -176
  95. data/tests/test_servers.rb +37 -41
  96. data/tests/test_smtpserver.rb +47 -55
  97. data/tests/test_spawn.rb +284 -291
  98. data/tests/test_ssl_args.rb +1 -1
  99. data/tests/test_ssl_methods.rb +1 -1
  100. data/tests/test_ssl_verify.rb +82 -0
  101. data/tests/test_timers.rb +81 -88
  102. data/tests/test_ud.rb +0 -7
  103. data/tests/testem.rb +1 -1
  104. metadata +52 -36
  105. data/lib/em/eventable.rb +0 -39
  106. data/lib/eventmachine_version.rb +0 -31
  107. data/lib/protocols/header_and_content.rb +0 -129
  108. data/lib/protocols/httpcli2.rb +0 -803
  109. data/lib/protocols/httpclient.rb +0 -270
  110. data/lib/protocols/linetext2.rb +0 -161
  111. data/lib/protocols/postgres.rb +0 -261
  112. data/lib/protocols/saslauth.rb +0 -179
  113. data/lib/protocols/smtpclient.rb +0 -308
  114. data/lib/protocols/smtpserver.rb +0 -556
  115. data/lib/protocols/stomp.rb +0 -153
  116. data/tests/test_eventables.rb +0 -77
@@ -1,8 +1,11 @@
1
- $Id$
2
-
3
1
  = RUBY/EventMachine
4
2
 
5
3
  Homepage:: http://rubyeventmachine.com
4
+ Rubyforge Page:: http://rubyforge.org/projects/eventmachine
5
+ Google Group:: http://groups.google.com/group/eventmachine
6
+ Mailing List:: http://rubyforge.org/pipermail/eventmachine-talk
7
+ RDoc:: http://eventmachine.rubyforge.org
8
+ IRC:: ##eventmachine on irc.freenode.net
6
9
  Copyright:: (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
7
10
  Email:: gmail address: garbagecat10
8
11
 
@@ -57,18 +60,23 @@ improved.
57
60
 
58
61
  Here's a fully-functional echo server written with EventMachine:
59
62
 
60
- require 'rubygems'
61
- require 'eventmachine'
63
+ require 'eventmachine'
62
64
 
63
- module EchoServer
64
- def receive_data data
65
- send_data ">>>you sent: #{data}"
66
- close_connection if data =~ /quit/i
67
- end
68
- end
65
+ module EchoServer
66
+ def post_init
67
+ puts "-- someone connected to the echo server!"
68
+ end
69
69
 
70
- EventMachine::run {
71
- EventMachine::start_server "192.168.0.100", 8081, EchoServer
72
- }
70
+ def receive_data data
71
+ send_data ">>>you sent: #{data}"
72
+ close_connection if data =~ /quit/i
73
+ end
73
74
 
75
+ def unbind
76
+ puts "-- someone disconnected from the echo server!"
77
+ end
78
+ end
74
79
 
80
+ EventMachine::run {
81
+ EventMachine::start_server "127.0.0.1", 8081, EchoServer
82
+ }
data/Rakefile CHANGED
@@ -87,8 +87,8 @@ Spec = Gem::Specification.new do |s|
87
87
  s.platform = Gem::Platform::RUBY
88
88
 
89
89
  s.has_rdoc = true
90
- s.rdoc_options = %w(--title EventMachine --main docs/README --line-numbers)
91
- s.extra_rdoc_files = Dir['docs/*']
90
+ s.rdoc_options = %w(--title EventMachine --main README --line-numbers -x lib/em/version -x lib/emva -x lib/evma/ -x lib/pr_eventmachine -x lib/jeventmachine)
91
+ s.extra_rdoc_files = Dir['README,docs/*']
92
92
 
93
93
  s.files = `git ls-files`.split("\n")
94
94
 
@@ -124,7 +124,7 @@ of EventMachine is to enable programs to easily interface with other programs
124
124
  using TCP/IP, especially if custom protocols are required.
125
125
  EOD
126
126
 
127
- require 'lib/eventmachine_version'
127
+ require 'lib/em/version'
128
128
  s.version = EventMachine::VERSION
129
129
  end
130
130
 
@@ -132,6 +132,10 @@ if RUBY_PLATFORM =~ /mswin/
132
132
  Spec.platform = 'x86-mswin32-60'
133
133
  Spec.files += %w[ lib/rubyeventmachine.so lib/fastfilereaderext.so ]
134
134
  Spec.extensions = nil
135
+ elsif RUBY_PLATFORM =~ /java/
136
+ Spec.platform = 'java'
137
+ Spec.files += %w[ lib/em_reactor.jar ]
138
+ Spec.extensions = nil
135
139
  end
136
140
 
137
141
  # this is a hack right now, it requires installing msysgit in the global path so it can use tar/curl/etc.
@@ -181,6 +185,7 @@ namespace :win32 do
181
185
  end
182
186
  end
183
187
 
188
+ desc "build binary win32 gem"
184
189
  task :gem => :build_openssl do
185
190
  Rake::Task['build'].invoke
186
191
  Rake::Task['gem'].invoke
@@ -220,7 +225,7 @@ namespace :ext do
220
225
  end
221
226
  end
222
227
  end
223
-
228
+
224
229
  namespace :java do
225
230
  # This task creates the JRuby JAR file and leaves it in the lib directory.
226
231
  # This step is required before executing the jgem task.
@@ -244,6 +249,11 @@ namespace :java do
244
249
  sh "jar -cf em_reactor.jar com/rubyeventmachine/*.class"
245
250
  end
246
251
  end
252
+
253
+ desc "build a java binary gem"
254
+ task :gem => :build do
255
+ Rake::Task['gem'].invoke
256
+ end
247
257
  end
248
258
 
249
259
  task :gemspec => :clobber do
data/docs/DEFERRABLES CHANGED
@@ -1,10 +1,5 @@
1
- $Id$
2
-
3
- [DOCUMENT UNDER CONSTRUCTION]
4
-
5
1
  EventMachine (EM) adds two different formalisms for lightweight concurrency to the Ruby programmer's toolbox: spawned processes and deferrables. This note will show you how to use deferrables. For more information, see the separate document LIGHTWEIGHT_CONCURRENCY.
6
2
 
7
-
8
3
  === What are Deferrables?
9
4
 
10
5
  EventMachine's Deferrable borrows heavily from the "deferred" object in Python's "Twisted" event-handling framework. Here's a minimal example that illustrates Deferrable:
data/docs/INSTALL CHANGED
@@ -1,5 +1,3 @@
1
- $Id$
2
-
3
1
  If you have obtained an EventMachine source-tarball (.tar.gz):
4
2
  unzip and untar the tarball, and enter the directory that is
5
3
  created. In that directory, say:
@@ -7,8 +5,8 @@ ruby setup.rb
7
5
  (You may need to be root to execute this command.)
8
6
 
9
7
  To create documentation for EventMachine, simply type:
10
- rdoc
11
- in the distro directory. Rdocs will be created in subdirectory doc.
8
+ rake rdoc
9
+ in the distro directory. Rdocs will be created in subdirectory rdoc.
12
10
 
13
11
  If you have obtained a gem version of EventMachine, install it in the
14
12
  usual way (gem install eventmachine). You may need superuser privileges
data/docs/LEGAL CHANGED
@@ -19,7 +19,7 @@ setup.rb
19
19
  the GNU LGPL, Lesser General Public License version 2.1.
20
20
 
21
21
 
22
- lib/protocols/buftok.rb
22
+ lib/em/buftok.rb
23
23
  This file is Copyright (C) 2007 by Tony Arcieri. This file is
24
24
  covered by the terms of Ruby's License (see the file COPYING).
25
25
 
@@ -1,5 +1,3 @@
1
- $Id$
2
-
3
1
  EventMachine (EM) adds two different formalisms for lightweight concurrency to the Ruby programmer's toolbox: spawned processes and deferrables. This note will show you how to use them.
4
2
 
5
3
 
data/docs/PURE_RUBY CHANGED
@@ -1,5 +1,3 @@
1
- $Id$
2
-
3
1
  EventMachine is supplied in three alternative versions.
4
2
 
5
3
  1) A version that includes a Ruby extension written in C++. This version requires compilation;
data/docs/RELEASE_NOTES CHANGED
@@ -1,5 +1,3 @@
1
- $Id$
2
-
3
1
  RUBY/EventMachine RELEASE NOTES
4
2
 
5
3
  --------------------------------------------------
data/docs/SMTP CHANGED
@@ -1,9 +1,2 @@
1
- $Id$
2
-
3
-
4
- [DOCUMENT UNDER CONSTRUCTION]
5
-
6
1
  This note details the usage of EventMachine's built-in support for SMTP. EM supports both client and server connections, which will be described in separate sections.
7
2
 
8
-
9
-
@@ -1,7 +1,3 @@
1
- $Id$
2
-
3
- [DOCUMENT UNDER CONSTRUCTION]
4
-
5
1
  EventMachine (EM) adds two different formalisms for lightweight concurrency to the Ruby programmer's toolbox: spawned processes and deferrables. This note will show you how to use spawned processes. For more information, see the separate document LIGHTWEIGHT_CONCURRENCY.
6
2
 
7
3
 
data/docs/TODO CHANGED
@@ -1,5 +1,3 @@
1
- $Id$
2
-
3
1
  TODO List:
4
2
 
5
3
  12Aug06: Noticed by Don Stocks. A TCP connect-request that results
data/eventmachine.gemspec CHANGED
@@ -1,32 +1,41 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- Gem::Specification.new do |s|
4
- s.name = %q{eventmachine}
5
- s.version = "0.12.6"
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-07}
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/ChangeLog", "docs/COPYING", "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", "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_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
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{eventmachine}
5
+ s.version = "0.12.8"
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-05-22}
10
+ s.description = %q{EventMachine implements a fast, single-threaded engine for arbitrary network
11
+ communications. It's extremely easy to use in Ruby. EventMachine wraps all
12
+ interactions with IP sockets, allowing programs to concentrate on the
13
+ implementation of network protocols. It can be used to create both network
14
+ servers and clients. To create a server or client, a Ruby program only needs
15
+ to specify the IP address and port, and provide a Module that implements the
16
+ communications protocol. Implementations of several standard network protocols
17
+ are provided with the package, primarily to serve as examples. The real goal
18
+ of EventMachine is to enable programs to easily interface with other programs
19
+ using TCP/IP, especially if custom protocols are required.
20
+ }
21
+ s.email = %q{garbagecat10@gmail.com}
22
+ s.extensions = ["ext/extconf.rb", "ext/fastfilereader/extconf.rb"]
23
+ s.has_rdoc = true
24
+ 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/RELEASE_NOTES", "docs/SMTP", "docs/SPAWNED_PROCESSES", "docs/TODO", "eventmachine.gemspec", "examples/ex_channel.rb", "examples/ex_queue.rb", "examples/helper.rb", "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/buftok.rb", "lib/em/callback.rb", "lib/em/channel.rb", "lib/em/connection.rb", "lib/em/deferrable.rb", "lib/em/file_watch.rb", "lib/em/future.rb", "lib/em/messages.rb", "lib/em/process_watch.rb", "lib/em/processes.rb", "lib/em/protocols.rb", "lib/em/protocols/header_and_content.rb", "lib/em/protocols/httpclient.rb", "lib/em/protocols/httpclient2.rb", "lib/em/protocols/line_and_text.rb", "lib/em/protocols/linetext2.rb", "lib/em/protocols/memcache.rb", "lib/em/protocols/object_protocol.rb", "lib/em/protocols/postgres3.rb", "lib/em/protocols/saslauth.rb", "lib/em/protocols/smtpclient.rb", "lib/em/protocols/smtpserver.rb", "lib/em/protocols/stomp.rb", "lib/em/protocols/tcptest.rb", "lib/em/queue.rb", "lib/em/spawnable.rb", "lib/em/streamer.rb", "lib/em/timers.rb", "lib/em/version.rb", "lib/eventmachine.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", "setup.rb", "tasks/cpp.rake", "tasks/project.rake", "tasks/tests.rake", "tests/client.crt", "tests/client.key", "tests/test_attach.rb", "tests/test_basic.rb", "tests/test_channel.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_exc.rb", "tests/test_file_watch.rb", "tests/test_futures.rb", "tests/test_handler_check.rb", "tests/test_hc.rb", "tests/test_httpclient.rb", "tests/test_httpclient2.rb", "tests/test_inactivity_timeout.rb", "tests/test_kb.rb", "tests/test_ltp.rb", "tests/test_ltp2.rb", "tests/test_next_tick.rb", "tests/test_object_protocol.rb", "tests/test_process_watch.rb", "tests/test_processes.rb", "tests/test_proxy_connection.rb", "tests/test_pure.rb", "tests/test_queue.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_ssl_verify.rb", "tests/test_timers.rb", "tests/test_ud.rb", "tests/testem.rb", "web/whatis"]
25
+ s.homepage = %q{http://rubyeventmachine.com}
26
+ s.rdoc_options = ["--title", "EventMachine", "--main", "README", "--line-numbers", "-x", "lib/em/version", "-x", "lib/emva", "-x", "lib/evma/", "-x", "lib/pr_eventmachine", "-x", "lib/jeventmachine"]
27
+ s.require_paths = ["lib"]
28
+ s.rubyforge_project = %q{eventmachine}
29
+ s.rubygems_version = %q{1.3.3}
30
+ s.summary = %q{Ruby/EventMachine library}
31
+
32
+ if s.respond_to? :specification_version then
33
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
34
+ s.specification_version = 3
35
+
36
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
37
+ else
38
+ end
39
+ else
40
+ end
41
+ end
@@ -0,0 +1,43 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ EM.run do
4
+
5
+ # Create a channel to push data to, this could be stocks...
6
+ RandChannel = EM::Channel.new
7
+
8
+ # The server simply subscribes client connections to the channel on connect,
9
+ # and unsubscribes them on disconnect.
10
+ class Server < EM::Connection
11
+ def self.start(host = '127.0.0.1', port = 8000)
12
+ EM.start_server(host, port, self)
13
+ end
14
+
15
+ def post_init
16
+ @sid = RandChannel.subscribe { |m| send_data "#{m.inspect}\n" }
17
+ end
18
+
19
+ def unbind
20
+ RandChannel.unsubscribe @sid
21
+ end
22
+ end
23
+ Server.start
24
+
25
+ # Two client connections, that just print what they receive.
26
+ 2.times do
27
+ EM.connect('127.0.0.1', 8000) do |c|
28
+ c.extend EM::P::LineText2
29
+ def c.receive_line(line)
30
+ puts "Subscriber: #{signature} got #{line}"
31
+ end
32
+ EM.add_timer(2) { c.close_connection }
33
+ end
34
+ end
35
+
36
+ # This part of the example is more fake, but imagine sleep was in fact a
37
+ # long running calculation to achieve the value.
38
+ 40.times do
39
+ EM.defer lambda { v = sleep(rand * 2); RandChannel << [Time.now, v] }
40
+ end
41
+
42
+ EM.add_timer(5) { EM.stop }
43
+ end
@@ -0,0 +1,2 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
@@ -0,0 +1,2 @@
1
+ $:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
2
+ require 'eventmachine'
data/ext/cmain.cpp CHANGED
@@ -1,586 +1,685 @@
1
- /*****************************************************************************
2
-
3
- $Id$
4
-
5
- File: cmain.cpp
6
- Date: 06Apr06
7
-
8
- Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
9
- Gmail: blackhedd
10
-
11
- This program is free software; you can redistribute it and/or modify
12
- it under the terms of either: 1) the GNU General Public License
13
- as published by the Free Software Foundation; either version 2 of the
14
- License, or (at your option) any later version; or 2) Ruby's License.
15
-
16
- See the file COPYING for complete licensing information.
17
-
18
- *****************************************************************************/
19
-
20
- #include "project.h"
21
-
22
-
23
- static EventMachine_t *EventMachine;
24
- static int bUseEpoll = 0;
25
- static int bUseKqueue = 0;
26
-
27
- extern "C" void ensure_eventmachine (const char *caller = "unknown caller")
28
- {
29
- if (!EventMachine) {
30
- const int err_size = 128;
31
- char err_string[err_size];
32
- snprintf (err_string, err_size, "eventmachine not initialized: %s", caller);
33
- #ifdef BUILD_FOR_RUBY
34
- rb_raise(rb_eRuntimeError, err_string);
35
- #else
36
- throw std::runtime_error (err_string);
37
- #endif
38
- }
39
- }
40
-
41
- /***********************
42
- evma_initialize_library
43
- ***********************/
44
-
45
- extern "C" void evma_initialize_library (void(*cb)(const char*, int, const char*, int))
46
- {
47
- // Probably a bad idea to mess with the signal mask of a process
48
- // we're just being linked into.
49
- //InstallSignalHandlers();
50
- if (EventMachine)
51
- #ifdef BUILD_FOR_RUBY
52
- rb_raise(rb_eRuntimeError, "eventmachine already initialized: evma_initialize_library");
53
- #else
54
- throw std::runtime_error ("eventmachine already initialized: evma_initialize_library");
55
- #endif
56
- EventMachine = new EventMachine_t (cb);
57
- if (bUseEpoll)
58
- EventMachine->_UseEpoll();
59
- if (bUseKqueue)
60
- EventMachine->_UseKqueue();
61
- }
62
-
63
-
64
- /********************
65
- evma_release_library
66
- ********************/
67
-
68
- extern "C" void evma_release_library()
69
- {
70
- ensure_eventmachine("evma_release_library");
71
- delete EventMachine;
72
- EventMachine = NULL;
73
- }
74
-
75
-
76
- /****************
77
- evma_run_machine
78
- ****************/
79
-
80
- extern "C" void evma_run_machine()
81
- {
82
- ensure_eventmachine("evma_run_machine");
83
- EventMachine->Run();
84
- }
85
-
86
-
87
- /**************************
88
- evma_install_oneshot_timer
89
- **************************/
90
-
91
- extern "C" const char *evma_install_oneshot_timer (int seconds)
92
- {
93
- ensure_eventmachine("evma_install_oneshot_timer");
94
- return EventMachine->InstallOneshotTimer (seconds);
95
- }
96
-
97
-
98
- /**********************
99
- evma_connect_to_server
100
- **********************/
101
-
102
- extern "C" const char *evma_connect_to_server (const char *server, int port)
103
- {
104
- ensure_eventmachine("evma_connect_to_server");
105
- return EventMachine->ConnectToServer (server, port);
106
- }
107
-
108
- /***************************
109
- evma_connect_to_unix_server
110
- ***************************/
111
-
112
- extern "C" const char *evma_connect_to_unix_server (const char *server)
113
- {
114
- ensure_eventmachine("evma_connect_to_unix_server");
115
- return EventMachine->ConnectToUnixServer (server);
116
- }
117
-
118
- /**************
119
- evma_attach_fd
120
- **************/
121
-
122
- extern "C" const char *evma_attach_fd (int file_descriptor, int notify_readable, int notify_writable)
123
- {
124
- ensure_eventmachine("evma_attach_fd");
125
- return EventMachine->AttachFD (file_descriptor, (notify_readable ? true : false), (notify_writable ? true : false));
126
- }
127
-
128
- /**************
129
- evma_detach_fd
130
- **************/
131
-
132
- extern "C" int evma_detach_fd (const char *binding)
133
- {
134
- ensure_eventmachine("evma_dettach_fd");
135
- EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
136
- if (ed)
137
- return EventMachine->DetachFD (ed);
138
- else
139
- #ifdef BUILD_FOR_RUBY
140
- rb_raise(rb_eRuntimeError, "invalid binding to detach");
141
- #else
142
- throw std::runtime_error ("invalid binding to detach");
143
- #endif
144
- }
145
-
146
- /**********************
147
- evma_create_tcp_server
148
- **********************/
149
-
150
- extern "C" const char *evma_create_tcp_server (const char *address, int port)
151
- {
152
- ensure_eventmachine("evma_create_tcp_server");
153
- return EventMachine->CreateTcpServer (address, port);
154
- }
155
-
156
- /******************************
157
- evma_create_unix_domain_server
158
- ******************************/
159
-
160
- extern "C" const char *evma_create_unix_domain_server (const char *filename)
161
- {
162
- ensure_eventmachine("evma_create_unix_domain_server");
163
- return EventMachine->CreateUnixDomainServer (filename);
164
- }
165
-
166
- /*************************
167
- evma_open_datagram_socket
168
- *************************/
169
-
170
- extern "C" const char *evma_open_datagram_socket (const char *address, int port)
171
- {
172
- ensure_eventmachine("evma_open_datagram_socket");
173
- return EventMachine->OpenDatagramSocket (address, port);
174
- }
175
-
176
- /******************
177
- evma_open_keyboard
178
- ******************/
179
-
180
- extern "C" const char *evma_open_keyboard()
181
- {
182
- ensure_eventmachine("evma_open_keyboard");
183
- return EventMachine->OpenKeyboard();
184
- }
185
-
186
-
187
-
188
- /****************************
189
- evma_send_data_to_connection
190
- ****************************/
191
-
192
- extern "C" int evma_send_data_to_connection (const char *binding, const char *data, int data_length)
193
- {
194
- ensure_eventmachine("evma_send_data_to_connection");
195
- return ConnectionDescriptor::SendDataToConnection (binding, data, data_length);
196
- }
197
-
198
- /******************
199
- evma_send_datagram
200
- ******************/
201
-
202
- extern "C" int evma_send_datagram (const char *binding, const char *data, int data_length, const char *address, int port)
203
- {
204
- ensure_eventmachine("evma_send_datagram");
205
- return DatagramDescriptor::SendDatagram (binding, data, data_length, address, port);
206
- }
207
-
208
-
209
- /*********************
210
- evma_close_connection
211
- *********************/
212
-
213
- extern "C" void evma_close_connection (const char *binding, int after_writing)
214
- {
215
- ensure_eventmachine("evma_close_connection");
216
- ConnectionDescriptor::CloseConnection (binding, (after_writing ? true : false));
217
- }
218
-
219
- /***********************************
220
- evma_report_connection_error_status
221
- ***********************************/
222
-
223
- extern "C" int evma_report_connection_error_status (const char *binding)
224
- {
225
- ensure_eventmachine("evma_report_connection_error_status");
226
- return ConnectionDescriptor::ReportErrorStatus (binding);
227
- }
228
-
229
- /********************
230
- evma_stop_tcp_server
231
- ********************/
232
-
233
- extern "C" void evma_stop_tcp_server (const char *binding)
234
- {
235
- ensure_eventmachine("evma_stop_tcp_server");
236
- AcceptorDescriptor::StopAcceptor (binding);
237
- }
238
-
239
-
240
- /*****************
241
- evma_stop_machine
242
- *****************/
243
-
244
- extern "C" void evma_stop_machine()
245
- {
246
- ensure_eventmachine("evma_stop_machine");
247
- EventMachine->ScheduleHalt();
248
- }
249
-
250
-
251
- /**************
252
- evma_start_tls
253
- **************/
254
-
255
- extern "C" void evma_start_tls (const char *binding)
256
- {
257
- ensure_eventmachine("evma_start_tls");
258
- EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
259
- if (ed)
260
- ed->StartTls();
261
- }
262
-
263
- /******************
264
- evma_set_tls_parms
265
- ******************/
266
-
267
- extern "C" void evma_set_tls_parms (const char *binding, const char *privatekey_filename, const char *certchain_filename)
268
- {
269
- ensure_eventmachine("evma_set_tls_parms");
270
- EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
271
- if (ed)
272
- ed->SetTlsParms (privatekey_filename, certchain_filename);
273
- }
274
-
275
- /**************
276
- evma_get_peer_cert
277
- **************/
278
-
279
- #ifdef WITH_SSL
280
- extern "C" X509 *evma_get_peer_cert (const char *binding)
281
- {
282
- ensure_eventmachine("evma_get_peer_cert");
283
- EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
284
- if (ed)
285
- return ed->GetPeerCert();
286
- return NULL;
287
- }
288
- #endif
289
-
290
- /*****************
291
- evma_get_peername
292
- *****************/
293
-
294
- extern "C" int evma_get_peername (const char *binding, struct sockaddr *sa)
295
- {
296
- ensure_eventmachine("evma_get_peername");
297
- EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
298
- if (ed) {
299
- return ed->GetPeername (sa) ? 1 : 0;
300
- }
301
- else
302
- return 0;
303
- }
304
-
305
- /*****************
306
- evma_get_sockname
307
- *****************/
308
-
309
- extern "C" int evma_get_sockname (const char *binding, struct sockaddr *sa)
310
- {
311
- ensure_eventmachine("evma_get_sockname");
312
- EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
313
- if (ed) {
314
- return ed->GetSockname (sa) ? 1 : 0;
315
- }
316
- else
317
- return 0;
318
- }
319
-
320
- /***********************
321
- evma_get_subprocess_pid
322
- ***********************/
323
-
324
- extern "C" int evma_get_subprocess_pid (const char *binding, pid_t *pid)
325
- {
326
- ensure_eventmachine("evma_get_subprocess_pid");
327
- #ifdef OS_UNIX
328
- PipeDescriptor *pd = dynamic_cast <PipeDescriptor*> (Bindable_t::GetObject (binding));
329
- if (pd) {
330
- return pd->GetSubprocessPid (pid) ? 1 : 0;
331
- }
332
- else if (pid && EventMachine->SubprocessPid) {
333
- *pid = EventMachine->SubprocessPid;
334
- return 1;
335
- }
336
- else
337
- return 0;
338
- #else
339
- return 0;
340
- #endif
341
- }
342
-
343
- /**************************
344
- evma_get_subprocess_status
345
- **************************/
346
-
347
- extern "C" int evma_get_subprocess_status (const char *binding, int *status)
348
- {
349
- ensure_eventmachine("evma_get_subprocess_status");
350
- if (status) {
351
- *status = EventMachine->SubprocessExitStatus;
352
- return 1;
353
- }
354
- else
355
- return 0;
356
- }
357
-
358
- /*************************
359
- evma_get_connection_count
360
- *************************/
361
-
362
- extern "C" int evma_get_connection_count()
363
- {
364
- ensure_eventmachine("evma_get_connection_count");
365
- return EventMachine->GetConnectionCount();
366
- }
367
-
368
- /*********************
369
- evma_signal_loopbreak
370
- *********************/
371
-
372
- extern "C" void evma_signal_loopbreak()
373
- {
374
- ensure_eventmachine("evma_signal_loopbreak");
375
- EventMachine->SignalLoopBreaker();
376
- }
377
-
378
-
379
-
380
- /****************
381
- evma__write_file
382
- ****************/
383
-
384
- extern "C" const char *evma__write_file (const char *filename)
385
- {
386
- ensure_eventmachine("evma__write_file");
387
- return EventMachine->_OpenFileForWriting (filename);
388
- }
389
-
390
-
391
- /********************************
392
- evma_get_comm_inactivity_timeout
393
- ********************************/
394
-
395
- extern "C" int evma_get_comm_inactivity_timeout (const char *binding, int *value)
396
- {
397
- ensure_eventmachine("evma_get_comm_inactivity_timeout");
398
- EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
399
- if (ed) {
400
- return ed->GetCommInactivityTimeout (value);
401
- }
402
- else
403
- return 0; //Perhaps this should be an exception. Access to an unknown binding.
404
- }
405
-
406
- /********************************
407
- evma_set_comm_inactivity_timeout
408
- ********************************/
409
-
410
- extern "C" int evma_set_comm_inactivity_timeout (const char *binding, int *value)
411
- {
412
- ensure_eventmachine("evma_set_comm_inactivity_timeout");
413
- EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
414
- if (ed) {
415
- return ed->SetCommInactivityTimeout (value);
416
- }
417
- else
418
- return 0; //Perhaps this should be an exception. Access to an unknown binding.
419
- }
420
-
421
-
422
- /**********************
423
- evma_set_timer_quantum
424
- **********************/
425
-
426
- extern "C" void evma_set_timer_quantum (int interval)
427
- {
428
- ensure_eventmachine("evma_set_timer_quantum");
429
- EventMachine->SetTimerQuantum (interval);
430
- }
431
-
432
-
433
- /************************
434
- evma_get_max_timer_count
435
- ************************/
436
-
437
- extern "C" int evma_get_max_timer_count()
438
- {
439
- return EventMachine_t::GetMaxTimerCount();
440
- }
441
-
442
-
443
- /************************
444
- evma_set_max_timer_count
445
- ************************/
446
-
447
- extern "C" void evma_set_max_timer_count (int ct)
448
- {
449
- // This may only be called if the reactor is not running.
450
-
451
- if (EventMachine)
452
- #ifdef BUILD_FOR_RUBY
453
- rb_raise(rb_eRuntimeError, "eventmachine already initialized: evma_set_max_timer_count");
454
- #else
455
- throw std::runtime_error ("eventmachine already initialized: evma_set_max_timer_count");
456
- #endif
457
- EventMachine_t::SetMaxTimerCount (ct);
458
- }
459
-
460
- /******************
461
- evma_setuid_string
462
- ******************/
463
-
464
- extern "C" void evma_setuid_string (const char *username)
465
- {
466
- // We do NOT need to be running an EM instance because this method is static.
467
- EventMachine_t::SetuidString (username);
468
- }
469
-
470
-
471
- /**********
472
- evma_popen
473
- **********/
474
-
475
- extern "C" const char *evma_popen (char * const*cmd_strings)
476
- {
477
- ensure_eventmachine("evma_popen");
478
- return EventMachine->Socketpair (cmd_strings);
479
- }
480
-
481
-
482
- /***************************
483
- evma_get_outbound_data_size
484
- ***************************/
485
-
486
- extern "C" int evma_get_outbound_data_size (const char *binding)
487
- {
488
- ensure_eventmachine("evma_get_outbound_data_size");
489
- EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
490
- return ed ? ed->GetOutboundDataSize() : 0;
491
- }
492
-
493
-
494
- /***********
495
- evma__epoll
496
- ***********/
497
-
498
- extern "C" void evma__epoll()
499
- {
500
- bUseEpoll = 1;
501
- }
502
-
503
- /************
504
- evma__kqueue
505
- ************/
506
-
507
- extern "C" void evma__kqueue()
508
- {
509
- bUseKqueue = 1;
510
- }
511
-
512
-
513
- /**********************
514
- evma_set_rlimit_nofile
515
- **********************/
516
-
517
- extern "C" int evma_set_rlimit_nofile (int nofiles)
518
- {
519
- return EventMachine_t::SetRlimitNofile (nofiles);
520
- }
521
-
522
-
523
- /*********************************
524
- evma_send_file_data_to_connection
525
- *********************************/
526
-
527
- extern "C" int evma_send_file_data_to_connection (const char *binding, const char *filename)
528
- {
529
- /* This is a sugaring over send_data_to_connection that reads a file into a
530
- * locally-allocated buffer, and sends the file data to the remote peer.
531
- * Return the number of bytes written to the caller.
532
- * TODO, needs to impose a limit on the file size. This is intended only for
533
- * small files. (I don't know, maybe 8K or less.) For larger files, use interleaved
534
- * I/O to avoid slowing the rest of the system down.
535
- * TODO: we should return a code rather than barf, in case of file-not-found.
536
- * TODO, does this compile on Windows?
537
- * TODO, given that we want this to work only with small files, how about allocating
538
- * the buffer on the stack rather than the heap?
539
- *
540
- * Modified 25Jul07. This now returns -1 on file-too-large; 0 for success, and a positive
541
- * errno in case of other errors.
542
- *
543
- /* Contributed by Kirk Haines.
544
- */
545
-
546
- char data[32*1024];
547
- int r;
548
-
549
- ensure_eventmachine("evma_send_file_data_to_connection");
550
-
551
- int Fd = open (filename, O_RDONLY);
552
-
553
- if (Fd < 0)
554
- return errno;
555
- // From here on, all early returns MUST close Fd.
556
-
557
- struct stat st;
558
- if (fstat (Fd, &st)) {
559
- int e = errno;
560
- close (Fd);
561
- return e;
562
- }
563
-
564
- int filesize = st.st_size;
565
- if (filesize <= 0) {
566
- close (Fd);
567
- return 0;
568
- }
569
- else if (filesize > sizeof(data)) {
570
- close (Fd);
571
- return -1;
572
- }
573
-
574
-
575
- r = read (Fd, data, filesize);
576
- if (r != filesize) {
577
- int e = errno;
578
- close (Fd);
579
- return e;
580
- }
581
- evma_send_data_to_connection (binding, data, r);
582
- close (Fd);
583
-
584
- return 0;
585
- }
586
-
1
+ /*****************************************************************************
2
+
3
+ $Id$
4
+
5
+ File: cmain.cpp
6
+ Date: 06Apr06
7
+
8
+ Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
9
+ Gmail: blackhedd
10
+
11
+ This program is free software; you can redistribute it and/or modify
12
+ it under the terms of either: 1) the GNU General Public License
13
+ as published by the Free Software Foundation; either version 2 of the
14
+ License, or (at your option) any later version; or 2) Ruby's License.
15
+
16
+ See the file COPYING for complete licensing information.
17
+
18
+ *****************************************************************************/
19
+
20
+ #include "project.h"
21
+
22
+
23
+ static EventMachine_t *EventMachine;
24
+ static int bUseEpoll = 0;
25
+ static int bUseKqueue = 0;
26
+
27
+ extern "C" void ensure_eventmachine (const char *caller = "unknown caller")
28
+ {
29
+ if (!EventMachine) {
30
+ const int err_size = 128;
31
+ char err_string[err_size];
32
+ snprintf (err_string, err_size, "eventmachine not initialized: %s", caller);
33
+ #ifdef BUILD_FOR_RUBY
34
+ rb_raise(rb_eRuntimeError, err_string);
35
+ #else
36
+ throw std::runtime_error (err_string);
37
+ #endif
38
+ }
39
+ }
40
+
41
+ /***********************
42
+ evma_initialize_library
43
+ ***********************/
44
+
45
+ extern "C" void evma_initialize_library (void(*cb)(const char*, int, const char*, int))
46
+ {
47
+ // Probably a bad idea to mess with the signal mask of a process
48
+ // we're just being linked into.
49
+ //InstallSignalHandlers();
50
+ if (EventMachine)
51
+ #ifdef BUILD_FOR_RUBY
52
+ rb_raise(rb_eRuntimeError, "eventmachine already initialized: evma_initialize_library");
53
+ #else
54
+ throw std::runtime_error ("eventmachine already initialized: evma_initialize_library");
55
+ #endif
56
+ EventMachine = new EventMachine_t (cb);
57
+ if (bUseEpoll)
58
+ EventMachine->_UseEpoll();
59
+ if (bUseKqueue)
60
+ EventMachine->_UseKqueue();
61
+ }
62
+
63
+
64
+ /********************
65
+ evma_release_library
66
+ ********************/
67
+
68
+ extern "C" void evma_release_library()
69
+ {
70
+ ensure_eventmachine("evma_release_library");
71
+ delete EventMachine;
72
+ EventMachine = NULL;
73
+ }
74
+
75
+
76
+ /****************
77
+ evma_run_machine
78
+ ****************/
79
+
80
+ extern "C" void evma_run_machine()
81
+ {
82
+ ensure_eventmachine("evma_run_machine");
83
+ EventMachine->Run();
84
+ }
85
+
86
+
87
+ /**************************
88
+ evma_install_oneshot_timer
89
+ **************************/
90
+
91
+ extern "C" const char *evma_install_oneshot_timer (int seconds)
92
+ {
93
+ ensure_eventmachine("evma_install_oneshot_timer");
94
+ return EventMachine->InstallOneshotTimer (seconds);
95
+ }
96
+
97
+
98
+ /**********************
99
+ evma_connect_to_server
100
+ **********************/
101
+
102
+ extern "C" const char *evma_connect_to_server (const char *bind_addr, int bind_port, const char *server, int port)
103
+ {
104
+ ensure_eventmachine("evma_connect_to_server");
105
+ return EventMachine->ConnectToServer (bind_addr, bind_port, server, port);
106
+ }
107
+
108
+ /***************************
109
+ evma_connect_to_unix_server
110
+ ***************************/
111
+
112
+ extern "C" const char *evma_connect_to_unix_server (const char *server)
113
+ {
114
+ ensure_eventmachine("evma_connect_to_unix_server");
115
+ return EventMachine->ConnectToUnixServer (server);
116
+ }
117
+
118
+ /**************
119
+ evma_attach_fd
120
+ **************/
121
+
122
+ extern "C" const char *evma_attach_fd (int file_descriptor, int notify_readable, int notify_writable)
123
+ {
124
+ ensure_eventmachine("evma_attach_fd");
125
+ return EventMachine->AttachFD (file_descriptor, (notify_readable ? true : false), (notify_writable ? true : false));
126
+ }
127
+
128
+ /**************
129
+ evma_detach_fd
130
+ **************/
131
+
132
+ extern "C" int evma_detach_fd (const char *binding)
133
+ {
134
+ ensure_eventmachine("evma_dettach_fd");
135
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
136
+ if (ed)
137
+ return EventMachine->DetachFD (ed);
138
+ else
139
+ #ifdef BUILD_FOR_RUBY
140
+ rb_raise(rb_eRuntimeError, "invalid binding to detach");
141
+ #else
142
+ throw std::runtime_error ("invalid binding to detach");
143
+ #endif
144
+ }
145
+
146
+ /**********************
147
+ evma_create_tcp_server
148
+ **********************/
149
+
150
+ extern "C" const char *evma_create_tcp_server (const char *address, int port)
151
+ {
152
+ ensure_eventmachine("evma_create_tcp_server");
153
+ return EventMachine->CreateTcpServer (address, port);
154
+ }
155
+
156
+ /******************************
157
+ evma_create_unix_domain_server
158
+ ******************************/
159
+
160
+ extern "C" const char *evma_create_unix_domain_server (const char *filename)
161
+ {
162
+ ensure_eventmachine("evma_create_unix_domain_server");
163
+ return EventMachine->CreateUnixDomainServer (filename);
164
+ }
165
+
166
+ /*************************
167
+ evma_open_datagram_socket
168
+ *************************/
169
+
170
+ extern "C" const char *evma_open_datagram_socket (const char *address, int port)
171
+ {
172
+ ensure_eventmachine("evma_open_datagram_socket");
173
+ return EventMachine->OpenDatagramSocket (address, port);
174
+ }
175
+
176
+ /******************
177
+ evma_open_keyboard
178
+ ******************/
179
+
180
+ extern "C" const char *evma_open_keyboard()
181
+ {
182
+ ensure_eventmachine("evma_open_keyboard");
183
+ return EventMachine->OpenKeyboard();
184
+ }
185
+
186
+ /*******************
187
+ evma_watch_filename
188
+ *******************/
189
+
190
+ extern "C" const char *evma_watch_filename (const char *fname)
191
+ {
192
+ ensure_eventmachine("evma_watch_filename");
193
+ return EventMachine->WatchFile(fname);
194
+ }
195
+
196
+ /*********************
197
+ evma_unwatch_filename
198
+ *********************/
199
+
200
+ extern "C" void evma_unwatch_filename (const char *sig)
201
+ {
202
+ ensure_eventmachine("evma_unwatch_file");
203
+ EventMachine->UnwatchFile(sig);
204
+ }
205
+
206
+ /**************
207
+ evma_watch_pid
208
+ **************/
209
+
210
+ extern "C" const char *evma_watch_pid (int pid)
211
+ {
212
+ ensure_eventmachine("evma_watch_pid");
213
+ return EventMachine->WatchPid(pid);
214
+ }
215
+
216
+ /****************
217
+ evma_unwatch_pid
218
+ ****************/
219
+
220
+ extern "C" void evma_unwatch_pid (const char *sig)
221
+ {
222
+ ensure_eventmachine("evma_unwatch_pid");
223
+ EventMachine->UnwatchPid(sig);
224
+ }
225
+
226
+ /****************************
227
+ evma_send_data_to_connection
228
+ ****************************/
229
+
230
+ extern "C" int evma_send_data_to_connection (const char *binding, const char *data, int data_length)
231
+ {
232
+ ensure_eventmachine("evma_send_data_to_connection");
233
+ return ConnectionDescriptor::SendDataToConnection (binding, data, data_length);
234
+ }
235
+
236
+ /******************
237
+ evma_send_datagram
238
+ ******************/
239
+
240
+ extern "C" int evma_send_datagram (const char *binding, const char *data, int data_length, const char *address, int port)
241
+ {
242
+ ensure_eventmachine("evma_send_datagram");
243
+ return DatagramDescriptor::SendDatagram (binding, data, data_length, address, port);
244
+ }
245
+
246
+
247
+ /*********************
248
+ evma_close_connection
249
+ *********************/
250
+
251
+ extern "C" void evma_close_connection (const char *binding, int after_writing)
252
+ {
253
+ ensure_eventmachine("evma_close_connection");
254
+ ConnectionDescriptor::CloseConnection (binding, (after_writing ? true : false));
255
+ }
256
+
257
+ /***********************************
258
+ evma_report_connection_error_status
259
+ ***********************************/
260
+
261
+ extern "C" int evma_report_connection_error_status (const char *binding)
262
+ {
263
+ ensure_eventmachine("evma_report_connection_error_status");
264
+ return ConnectionDescriptor::ReportErrorStatus (binding);
265
+ }
266
+
267
+ /********************
268
+ evma_stop_tcp_server
269
+ ********************/
270
+
271
+ extern "C" void evma_stop_tcp_server (const char *binding)
272
+ {
273
+ ensure_eventmachine("evma_stop_tcp_server");
274
+ AcceptorDescriptor::StopAcceptor (binding);
275
+ }
276
+
277
+
278
+ /*****************
279
+ evma_stop_machine
280
+ *****************/
281
+
282
+ extern "C" void evma_stop_machine()
283
+ {
284
+ ensure_eventmachine("evma_stop_machine");
285
+ EventMachine->ScheduleHalt();
286
+ }
287
+
288
+
289
+ /**************
290
+ evma_start_tls
291
+ **************/
292
+
293
+ extern "C" void evma_start_tls (const char *binding)
294
+ {
295
+ ensure_eventmachine("evma_start_tls");
296
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
297
+ if (ed)
298
+ ed->StartTls();
299
+ }
300
+
301
+ /******************
302
+ evma_set_tls_parms
303
+ ******************/
304
+
305
+ extern "C" void evma_set_tls_parms (const char *binding, const char *privatekey_filename, const char *certchain_filename, int verify_peer)
306
+ {
307
+ ensure_eventmachine("evma_set_tls_parms");
308
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
309
+ if (ed)
310
+ ed->SetTlsParms (privatekey_filename, certchain_filename, (verify_peer == 1 ? true : false));
311
+ }
312
+
313
+ /******************
314
+ evma_get_peer_cert
315
+ ******************/
316
+
317
+ #ifdef WITH_SSL
318
+ extern "C" X509 *evma_get_peer_cert (const char *binding)
319
+ {
320
+ ensure_eventmachine("evma_get_peer_cert");
321
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
322
+ if (ed)
323
+ return ed->GetPeerCert();
324
+ return NULL;
325
+ }
326
+ #endif
327
+
328
+ /********************
329
+ evma_accept_ssl_peer
330
+ ********************/
331
+
332
+ #ifdef WITH_SSL
333
+ extern "C" void evma_accept_ssl_peer (const char *binding)
334
+ {
335
+ ensure_eventmachine("evma_accept_ssl_peer");
336
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
337
+ if (cd)
338
+ cd->AcceptSslPeer();
339
+ }
340
+ #endif
341
+
342
+ /*****************
343
+ evma_get_peername
344
+ *****************/
345
+
346
+ extern "C" int evma_get_peername (const char *binding, struct sockaddr *sa)
347
+ {
348
+ ensure_eventmachine("evma_get_peername");
349
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
350
+ if (ed) {
351
+ return ed->GetPeername (sa) ? 1 : 0;
352
+ }
353
+ else
354
+ return 0;
355
+ }
356
+
357
+ /*****************
358
+ evma_get_sockname
359
+ *****************/
360
+
361
+ extern "C" int evma_get_sockname (const char *binding, struct sockaddr *sa)
362
+ {
363
+ ensure_eventmachine("evma_get_sockname");
364
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
365
+ if (ed) {
366
+ return ed->GetSockname (sa) ? 1 : 0;
367
+ }
368
+ else
369
+ return 0;
370
+ }
371
+
372
+ /***********************
373
+ evma_get_subprocess_pid
374
+ ***********************/
375
+
376
+ extern "C" int evma_get_subprocess_pid (const char *binding, pid_t *pid)
377
+ {
378
+ ensure_eventmachine("evma_get_subprocess_pid");
379
+ #ifdef OS_UNIX
380
+ PipeDescriptor *pd = dynamic_cast <PipeDescriptor*> (Bindable_t::GetObject (binding));
381
+ if (pd) {
382
+ return pd->GetSubprocessPid (pid) ? 1 : 0;
383
+ }
384
+ else if (pid && EventMachine->SubprocessPid) {
385
+ *pid = EventMachine->SubprocessPid;
386
+ return 1;
387
+ }
388
+ else
389
+ return 0;
390
+ #else
391
+ return 0;
392
+ #endif
393
+ }
394
+
395
+ /**************************
396
+ evma_get_subprocess_status
397
+ **************************/
398
+
399
+ extern "C" int evma_get_subprocess_status (const char *binding, int *status)
400
+ {
401
+ ensure_eventmachine("evma_get_subprocess_status");
402
+ if (status) {
403
+ *status = EventMachine->SubprocessExitStatus;
404
+ return 1;
405
+ }
406
+ else
407
+ return 0;
408
+ }
409
+
410
+ /*************************
411
+ evma_get_connection_count
412
+ *************************/
413
+
414
+ extern "C" int evma_get_connection_count()
415
+ {
416
+ ensure_eventmachine("evma_get_connection_count");
417
+ return EventMachine->GetConnectionCount();
418
+ }
419
+
420
+ /*********************
421
+ evma_signal_loopbreak
422
+ *********************/
423
+
424
+ extern "C" void evma_signal_loopbreak()
425
+ {
426
+ ensure_eventmachine("evma_signal_loopbreak");
427
+ EventMachine->SignalLoopBreaker();
428
+ }
429
+
430
+
431
+
432
+ /****************
433
+ evma__write_file
434
+ ****************/
435
+
436
+ extern "C" const char *evma__write_file (const char *filename)
437
+ {
438
+ ensure_eventmachine("evma__write_file");
439
+ return EventMachine->_OpenFileForWriting (filename);
440
+ }
441
+
442
+
443
+ /********************************
444
+ evma_get_comm_inactivity_timeout
445
+ ********************************/
446
+
447
+ extern "C" float evma_get_comm_inactivity_timeout (const char *binding)
448
+ {
449
+ ensure_eventmachine("evma_get_comm_inactivity_timeout");
450
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
451
+ if (ed) {
452
+ return ed->GetCommInactivityTimeout();
453
+ }
454
+ else
455
+ return 0.0; //Perhaps this should be an exception. Access to an unknown binding.
456
+ }
457
+
458
+ /********************************
459
+ evma_set_comm_inactivity_timeout
460
+ ********************************/
461
+
462
+ extern "C" int evma_set_comm_inactivity_timeout (const char *binding, float value)
463
+ {
464
+ ensure_eventmachine("evma_set_comm_inactivity_timeout");
465
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
466
+ if (ed) {
467
+ return ed->SetCommInactivityTimeout (value);
468
+ }
469
+ else
470
+ return 0; //Perhaps this should be an exception. Access to an unknown binding.
471
+ }
472
+
473
+
474
+ /**********************
475
+ evma_set_timer_quantum
476
+ **********************/
477
+
478
+ extern "C" void evma_set_timer_quantum (int interval)
479
+ {
480
+ ensure_eventmachine("evma_set_timer_quantum");
481
+ EventMachine->SetTimerQuantum (interval);
482
+ }
483
+
484
+
485
+ /************************
486
+ evma_get_max_timer_count
487
+ ************************/
488
+
489
+ extern "C" int evma_get_max_timer_count()
490
+ {
491
+ return EventMachine_t::GetMaxTimerCount();
492
+ }
493
+
494
+
495
+ /************************
496
+ evma_set_max_timer_count
497
+ ************************/
498
+
499
+ extern "C" void evma_set_max_timer_count (int ct)
500
+ {
501
+ // This may only be called if the reactor is not running.
502
+
503
+ if (EventMachine)
504
+ #ifdef BUILD_FOR_RUBY
505
+ rb_raise(rb_eRuntimeError, "eventmachine already initialized: evma_set_max_timer_count");
506
+ #else
507
+ throw std::runtime_error ("eventmachine already initialized: evma_set_max_timer_count");
508
+ #endif
509
+ EventMachine_t::SetMaxTimerCount (ct);
510
+ }
511
+
512
+ /******************
513
+ evma_setuid_string
514
+ ******************/
515
+
516
+ extern "C" void evma_setuid_string (const char *username)
517
+ {
518
+ // We do NOT need to be running an EM instance because this method is static.
519
+ EventMachine_t::SetuidString (username);
520
+ }
521
+
522
+
523
+ /**********
524
+ evma_popen
525
+ **********/
526
+
527
+ extern "C" const char *evma_popen (char * const*cmd_strings)
528
+ {
529
+ ensure_eventmachine("evma_popen");
530
+ return EventMachine->Socketpair (cmd_strings);
531
+ }
532
+
533
+
534
+ /***************************
535
+ evma_get_outbound_data_size
536
+ ***************************/
537
+
538
+ extern "C" int evma_get_outbound_data_size (const char *binding)
539
+ {
540
+ ensure_eventmachine("evma_get_outbound_data_size");
541
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
542
+ return ed ? ed->GetOutboundDataSize() : 0;
543
+ }
544
+
545
+
546
+ /**************
547
+ evma_set_epoll
548
+ **************/
549
+
550
+ extern "C" void evma_set_epoll (int use)
551
+ {
552
+ bUseEpoll = !!use;
553
+ }
554
+
555
+ /***************
556
+ evma_set_kqueue
557
+ ***************/
558
+
559
+ extern "C" void evma_set_kqueue (int use)
560
+ {
561
+ bUseKqueue = !!use;
562
+ }
563
+
564
+
565
+ /**********************
566
+ evma_set_rlimit_nofile
567
+ **********************/
568
+
569
+ extern "C" int evma_set_rlimit_nofile (int nofiles)
570
+ {
571
+ return EventMachine_t::SetRlimitNofile (nofiles);
572
+ }
573
+
574
+
575
+ /*********************************
576
+ evma_send_file_data_to_connection
577
+ *********************************/
578
+
579
+ extern "C" int evma_send_file_data_to_connection (const char *binding, const char *filename)
580
+ {
581
+ /* This is a sugaring over send_data_to_connection that reads a file into a
582
+ * locally-allocated buffer, and sends the file data to the remote peer.
583
+ * Return the number of bytes written to the caller.
584
+ * TODO, needs to impose a limit on the file size. This is intended only for
585
+ * small files. (I don't know, maybe 8K or less.) For larger files, use interleaved
586
+ * I/O to avoid slowing the rest of the system down.
587
+ * TODO: we should return a code rather than barf, in case of file-not-found.
588
+ * TODO, does this compile on Windows?
589
+ * TODO, given that we want this to work only with small files, how about allocating
590
+ * the buffer on the stack rather than the heap?
591
+ *
592
+ * Modified 25Jul07. This now returns -1 on file-too-large; 0 for success, and a positive
593
+ * errno in case of other errors.
594
+ *
595
+ /* Contributed by Kirk Haines.
596
+ */
597
+
598
+ char data[32*1024];
599
+ int r;
600
+
601
+ ensure_eventmachine("evma_send_file_data_to_connection");
602
+
603
+ int Fd = open (filename, O_RDONLY);
604
+
605
+ if (Fd < 0)
606
+ return errno;
607
+ // From here on, all early returns MUST close Fd.
608
+
609
+ struct stat st;
610
+ if (fstat (Fd, &st)) {
611
+ int e = errno;
612
+ close (Fd);
613
+ return e;
614
+ }
615
+
616
+ int filesize = st.st_size;
617
+ if (filesize <= 0) {
618
+ close (Fd);
619
+ return 0;
620
+ }
621
+ else if (filesize > sizeof(data)) {
622
+ close (Fd);
623
+ return -1;
624
+ }
625
+
626
+
627
+ r = read (Fd, data, filesize);
628
+ if (r != filesize) {
629
+ int e = errno;
630
+ close (Fd);
631
+ return e;
632
+ }
633
+ evma_send_data_to_connection (binding, data, r);
634
+ close (Fd);
635
+
636
+ return 0;
637
+ }
638
+
639
+
640
+ /****************
641
+ evma_start_proxy
642
+ *****************/
643
+
644
+ extern "C" void evma_start_proxy (const char *from, const char *to)
645
+ {
646
+ ensure_eventmachine("evma_start_proxy");
647
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (from));
648
+ if (ed)
649
+ ed->StartProxy(to);
650
+ }
651
+
652
+
653
+ /***************
654
+ evma_stop_proxy
655
+ ****************/
656
+
657
+ extern "C" void evma_stop_proxy (const char *from)
658
+ {
659
+ ensure_eventmachine("evma_stop_proxy");
660
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (from));
661
+ if (ed)
662
+ ed->StopProxy();
663
+ }
664
+
665
+
666
+ /***************************
667
+ evma_get_heartbeat_interval
668
+ ****************************/
669
+
670
+ extern "C" float evma_get_heartbeat_interval()
671
+ {
672
+ ensure_eventmachine("evma_get_heartbeat_interval");
673
+ return EventMachine->GetHeartbeatInterval();
674
+ }
675
+
676
+
677
+ /***************************
678
+ evma_set_heartbeat_interval
679
+ ****************************/
680
+
681
+ extern "C" int evma_set_heartbeat_interval(float interval)
682
+ {
683
+ ensure_eventmachine("evma_set_heartbeat_interval");
684
+ return EventMachine->SetHeartbeatInterval(interval);
685
+ }