crusher-eventmachine 0.12.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. data/README +81 -0
  2. data/Rakefile +370 -0
  3. data/docs/COPYING +60 -0
  4. data/docs/ChangeLog +211 -0
  5. data/docs/DEFERRABLES +246 -0
  6. data/docs/EPOLL +141 -0
  7. data/docs/GNU +281 -0
  8. data/docs/INSTALL +13 -0
  9. data/docs/KEYBOARD +42 -0
  10. data/docs/LEGAL +25 -0
  11. data/docs/LIGHTWEIGHT_CONCURRENCY +130 -0
  12. data/docs/PURE_RUBY +75 -0
  13. data/docs/RELEASE_NOTES +94 -0
  14. data/docs/SMTP +4 -0
  15. data/docs/SPAWNED_PROCESSES +148 -0
  16. data/docs/TODO +8 -0
  17. data/eventmachine.gemspec +40 -0
  18. data/examples/ex_channel.rb +43 -0
  19. data/examples/ex_queue.rb +2 -0
  20. data/examples/ex_tick_loop_array.rb +15 -0
  21. data/examples/ex_tick_loop_counter.rb +32 -0
  22. data/examples/helper.rb +2 -0
  23. data/ext/binder.cpp +124 -0
  24. data/ext/binder.h +46 -0
  25. data/ext/cmain.cpp +852 -0
  26. data/ext/cplusplus.cpp +202 -0
  27. data/ext/ed.cpp +1884 -0
  28. data/ext/ed.h +418 -0
  29. data/ext/em.cpp +2377 -0
  30. data/ext/em.h +239 -0
  31. data/ext/emwin.cpp +300 -0
  32. data/ext/emwin.h +94 -0
  33. data/ext/epoll.cpp +26 -0
  34. data/ext/epoll.h +25 -0
  35. data/ext/eventmachine.h +124 -0
  36. data/ext/eventmachine_cpp.h +96 -0
  37. data/ext/extconf.rb +150 -0
  38. data/ext/fastfilereader/extconf.rb +85 -0
  39. data/ext/fastfilereader/mapper.cpp +214 -0
  40. data/ext/fastfilereader/mapper.h +59 -0
  41. data/ext/fastfilereader/rubymain.cpp +127 -0
  42. data/ext/files.cpp +94 -0
  43. data/ext/files.h +65 -0
  44. data/ext/kb.cpp +79 -0
  45. data/ext/page.cpp +107 -0
  46. data/ext/page.h +51 -0
  47. data/ext/pipe.cpp +347 -0
  48. data/ext/project.h +157 -0
  49. data/ext/rubymain.cpp +1215 -0
  50. data/ext/sigs.cpp +89 -0
  51. data/ext/sigs.h +32 -0
  52. data/ext/ssl.cpp +460 -0
  53. data/ext/ssl.h +94 -0
  54. data/java/.classpath +8 -0
  55. data/java/.project +17 -0
  56. data/java/src/com/rubyeventmachine/EmReactor.java +571 -0
  57. data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
  58. data/java/src/com/rubyeventmachine/EventableChannel.java +69 -0
  59. data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +189 -0
  60. data/java/src/com/rubyeventmachine/EventableSocketChannel.java +364 -0
  61. data/java/src/com/rubyeventmachine/application/Application.java +194 -0
  62. data/java/src/com/rubyeventmachine/application/Connection.java +74 -0
  63. data/java/src/com/rubyeventmachine/application/ConnectionFactory.java +37 -0
  64. data/java/src/com/rubyeventmachine/application/DefaultConnectionFactory.java +46 -0
  65. data/java/src/com/rubyeventmachine/application/PeriodicTimer.java +38 -0
  66. data/java/src/com/rubyeventmachine/application/Timer.java +54 -0
  67. data/java/src/com/rubyeventmachine/tests/ApplicationTest.java +109 -0
  68. data/java/src/com/rubyeventmachine/tests/ConnectTest.java +148 -0
  69. data/java/src/com/rubyeventmachine/tests/EMTest.java +80 -0
  70. data/java/src/com/rubyeventmachine/tests/TestDatagrams.java +53 -0
  71. data/java/src/com/rubyeventmachine/tests/TestServers.java +75 -0
  72. data/java/src/com/rubyeventmachine/tests/TestTimers.java +90 -0
  73. data/lib/em/buftok.rb +138 -0
  74. data/lib/em/callback.rb +26 -0
  75. data/lib/em/channel.rb +57 -0
  76. data/lib/em/connection.rb +569 -0
  77. data/lib/em/deferrable.rb +206 -0
  78. data/lib/em/file_watch.rb +54 -0
  79. data/lib/em/future.rb +61 -0
  80. data/lib/em/iterator.rb +270 -0
  81. data/lib/em/messages.rb +66 -0
  82. data/lib/em/process_watch.rb +44 -0
  83. data/lib/em/processes.rb +119 -0
  84. data/lib/em/protocols.rb +36 -0
  85. data/lib/em/protocols/header_and_content.rb +138 -0
  86. data/lib/em/protocols/httpclient.rb +276 -0
  87. data/lib/em/protocols/httpclient2.rb +590 -0
  88. data/lib/em/protocols/line_and_text.rb +125 -0
  89. data/lib/em/protocols/linetext2.rb +161 -0
  90. data/lib/em/protocols/memcache.rb +323 -0
  91. data/lib/em/protocols/object_protocol.rb +45 -0
  92. data/lib/em/protocols/postgres3.rb +247 -0
  93. data/lib/em/protocols/saslauth.rb +175 -0
  94. data/lib/em/protocols/smtpclient.rb +357 -0
  95. data/lib/em/protocols/smtpserver.rb +640 -0
  96. data/lib/em/protocols/socks4.rb +66 -0
  97. data/lib/em/protocols/stomp.rb +200 -0
  98. data/lib/em/protocols/tcptest.rb +53 -0
  99. data/lib/em/pure_ruby.rb +1019 -0
  100. data/lib/em/queue.rb +62 -0
  101. data/lib/em/spawnable.rb +85 -0
  102. data/lib/em/streamer.rb +130 -0
  103. data/lib/em/tick_loop.rb +85 -0
  104. data/lib/em/timers.rb +57 -0
  105. data/lib/em/version.rb +3 -0
  106. data/lib/eventmachine.rb +1540 -0
  107. data/lib/evma.rb +32 -0
  108. data/lib/evma/callback.rb +32 -0
  109. data/lib/evma/container.rb +75 -0
  110. data/lib/evma/factory.rb +77 -0
  111. data/lib/evma/protocol.rb +87 -0
  112. data/lib/evma/reactor.rb +48 -0
  113. data/lib/jeventmachine.rb +257 -0
  114. data/setup.rb +1585 -0
  115. data/tasks/cpp.rake_example +77 -0
  116. data/tests/client.crt +31 -0
  117. data/tests/client.key +51 -0
  118. data/tests/test_attach.rb +136 -0
  119. data/tests/test_basic.rb +249 -0
  120. data/tests/test_channel.rb +63 -0
  121. data/tests/test_connection_count.rb +35 -0
  122. data/tests/test_defer.rb +49 -0
  123. data/tests/test_deferrable.rb +35 -0
  124. data/tests/test_epoll.rb +160 -0
  125. data/tests/test_error_handler.rb +35 -0
  126. data/tests/test_errors.rb +82 -0
  127. data/tests/test_exc.rb +55 -0
  128. data/tests/test_file_watch.rb +49 -0
  129. data/tests/test_futures.rb +198 -0
  130. data/tests/test_get_sock_opt.rb +30 -0
  131. data/tests/test_handler_check.rb +37 -0
  132. data/tests/test_hc.rb +190 -0
  133. data/tests/test_httpclient.rb +227 -0
  134. data/tests/test_httpclient2.rb +154 -0
  135. data/tests/test_inactivity_timeout.rb +50 -0
  136. data/tests/test_kb.rb +60 -0
  137. data/tests/test_ltp.rb +190 -0
  138. data/tests/test_ltp2.rb +317 -0
  139. data/tests/test_next_tick.rb +133 -0
  140. data/tests/test_object_protocol.rb +37 -0
  141. data/tests/test_pause.rb +70 -0
  142. data/tests/test_pending_connect_timeout.rb +48 -0
  143. data/tests/test_process_watch.rb +50 -0
  144. data/tests/test_processes.rb +128 -0
  145. data/tests/test_proxy_connection.rb +144 -0
  146. data/tests/test_pure.rb +134 -0
  147. data/tests/test_queue.rb +44 -0
  148. data/tests/test_running.rb +42 -0
  149. data/tests/test_sasl.rb +72 -0
  150. data/tests/test_send_file.rb +251 -0
  151. data/tests/test_servers.rb +76 -0
  152. data/tests/test_smtpclient.rb +83 -0
  153. data/tests/test_smtpserver.rb +85 -0
  154. data/tests/test_spawn.rb +322 -0
  155. data/tests/test_ssl_args.rb +79 -0
  156. data/tests/test_ssl_methods.rb +50 -0
  157. data/tests/test_ssl_verify.rb +82 -0
  158. data/tests/test_tick_loop.rb +59 -0
  159. data/tests/test_timers.rb +160 -0
  160. data/tests/test_ud.rb +36 -0
  161. data/tests/testem.rb +31 -0
  162. metadata +251 -0
data/docs/TODO ADDED
@@ -0,0 +1,8 @@
1
+ TODO List:
2
+
3
+ 12Aug06: Noticed by Don Stocks. A TCP connect-request that results
4
+ in a failed DNS resolution fires a fatal error back to user code.
5
+ Uuuuuugly. We should probably cause an unbind event to get fired
6
+ instead, and add some parameterization so the caller can detect
7
+ the nature of the failure.
8
+
@@ -0,0 +1,40 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'crusher-eventmachine'
5
+ s.version = "0.12.11"
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{2010-05-29}
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.files = ["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/ex_tick_loop_array.rb", "examples/ex_tick_loop_counter.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/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/application/Application.java", "java/src/com/rubyeventmachine/application/Connection.java", "java/src/com/rubyeventmachine/application/ConnectionFactory.java", "java/src/com/rubyeventmachine/application/DefaultConnectionFactory.java", "java/src/com/rubyeventmachine/application/PeriodicTimer.java", "java/src/com/rubyeventmachine/application/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/iterator.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/socks4.rb", "lib/em/protocols/stomp.rb", "lib/em/protocols/tcptest.rb", "lib/em/pure_ruby.rb", "lib/em/queue.rb", "lib/em/spawnable.rb", "lib/em/streamer.rb", "lib/em/tick_loop.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", "setup.rb", "tasks/cpp.rake_example", "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_deferrable.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_get_sock_opt.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_pause.rb", "tests/test_pending_connect_timeout.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_tick_loop.rb", "tests/test_timers.rb", "tests/test_ud.rb", "tests/testem.rb"]
24
+ s.homepage = %q{http://rubyeventmachine.com}
25
+ s.rdoc_options = ["--title", "EventMachine", "--main", "README", "--line-numbers", "-x", "lib/em/version", "-x", "lib/emva", "-x", "lib/evma/", "-x", "lib/jeventmachine"]
26
+ s.require_paths = ["lib"]
27
+ s.rubyforge_project = %q{eventmachine}
28
+ s.rubygems_version = %q{1.3.6}
29
+ s.summary = %q{Ruby/EventMachine library}
30
+
31
+ if s.respond_to? :specification_version then
32
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
33
+ s.specification_version = 3
34
+
35
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
36
+ else
37
+ end
38
+ else
39
+ end
40
+ 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,15 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ EM.run do
4
+ array = (1..100).to_a
5
+
6
+ tickloop = EM.tick_loop do
7
+ if array.empty?
8
+ :stop
9
+ else
10
+ puts array.shift
11
+ end
12
+ end
13
+
14
+ tickloop.on_stop { EM.stop }
15
+ end
@@ -0,0 +1,32 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class TickCounter
4
+ attr_reader :start_time, :count
5
+
6
+ def initialize
7
+ reset
8
+ @tick_loop = EM.tick_loop(method(:tick))
9
+ end
10
+
11
+ def reset
12
+ @count = 0
13
+ @start_time = EM.current_time
14
+ end
15
+
16
+ def tick
17
+ @count += 1
18
+ end
19
+
20
+ def rate
21
+ @count / (EM.current_time - @start_time)
22
+ end
23
+ end
24
+
25
+ period = 5
26
+ EM.run do
27
+ counter = TickCounter.new
28
+ EM.add_periodic_timer(period) do
29
+ puts "Ticks per second: #{counter.rate} (mean of last #{period}s)"
30
+ counter.reset
31
+ end
32
+ end
@@ -0,0 +1,2 @@
1
+ $:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
2
+ require 'eventmachine'
data/ext/binder.cpp ADDED
@@ -0,0 +1,124 @@
1
+ /*****************************************************************************
2
+
3
+ $Id$
4
+
5
+ File: binder.cpp
6
+ Date: 07Apr06
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
+ #define DEV_URANDOM "/dev/urandom"
23
+
24
+
25
+ map<unsigned long, Bindable_t*> Bindable_t::BindingBag;
26
+
27
+
28
+ /********************************
29
+ STATIC Bindable_t::CreateBinding
30
+ ********************************/
31
+
32
+ unsigned long Bindable_t::CreateBinding()
33
+ {
34
+ static unsigned long num = 0;
35
+ while(BindingBag[++num]);
36
+ return num;
37
+ }
38
+
39
+ #if 0
40
+ string Bindable_t::CreateBinding()
41
+ {
42
+ static int index = 0;
43
+ static string seed;
44
+
45
+ if ((index >= 1000000) || (seed.length() == 0)) {
46
+ #ifdef OS_UNIX
47
+ int fd = open (DEV_URANDOM, O_RDONLY);
48
+ if (fd < 0)
49
+ throw std::runtime_error ("No entropy device");
50
+
51
+ unsigned char u[16];
52
+ size_t r = read (fd, u, sizeof(u));
53
+ if (r < sizeof(u))
54
+ throw std::runtime_error ("Unable to read entropy device");
55
+
56
+ unsigned char *u1 = (unsigned char*)u;
57
+ char u2 [sizeof(u) * 2 + 1];
58
+
59
+ for (size_t i=0; i < sizeof(u); i++)
60
+ sprintf (u2 + (i * 2), "%02x", u1[i]);
61
+
62
+ seed = string (u2);
63
+ #endif
64
+
65
+
66
+ #ifdef OS_WIN32
67
+ UUID uuid;
68
+ UuidCreate (&uuid);
69
+ unsigned char *uuidstring = NULL;
70
+ UuidToString (&uuid, &uuidstring);
71
+ if (!uuidstring)
72
+ throw std::runtime_error ("Unable to read uuid");
73
+ seed = string ((const char*)uuidstring);
74
+
75
+ RpcStringFree (&uuidstring);
76
+ #endif
77
+
78
+ index = 0;
79
+
80
+
81
+ }
82
+
83
+ stringstream ss;
84
+ ss << seed << (++index);
85
+ return ss.str();
86
+ }
87
+ #endif
88
+
89
+ /*****************************
90
+ STATIC: Bindable_t::GetObject
91
+ *****************************/
92
+
93
+ Bindable_t *Bindable_t::GetObject (const unsigned long binding)
94
+ {
95
+ map<unsigned long, Bindable_t*>::const_iterator i = BindingBag.find (binding);
96
+ if (i != BindingBag.end())
97
+ return i->second;
98
+ else
99
+ return NULL;
100
+ }
101
+
102
+
103
+ /**********************
104
+ Bindable_t::Bindable_t
105
+ **********************/
106
+
107
+ Bindable_t::Bindable_t()
108
+ {
109
+ Binding = Bindable_t::CreateBinding();
110
+ BindingBag [Binding] = this;
111
+ }
112
+
113
+
114
+
115
+ /***********************
116
+ Bindable_t::~Bindable_t
117
+ ***********************/
118
+
119
+ Bindable_t::~Bindable_t()
120
+ {
121
+ BindingBag.erase (Binding);
122
+ }
123
+
124
+
data/ext/binder.h ADDED
@@ -0,0 +1,46 @@
1
+ /*****************************************************************************
2
+
3
+ $Id$
4
+
5
+ File: binder.h
6
+ Date: 07Apr06
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
+ #ifndef __ObjectBindings__H_
21
+ #define __ObjectBindings__H_
22
+
23
+
24
+ class Bindable_t
25
+ {
26
+ public:
27
+ static unsigned long CreateBinding();
28
+ static Bindable_t *GetObject (const unsigned long);
29
+ static map<unsigned long, Bindable_t*> BindingBag;
30
+
31
+ public:
32
+ Bindable_t();
33
+ virtual ~Bindable_t();
34
+
35
+ const unsigned long GetBinding() {return Binding;}
36
+
37
+ private:
38
+ unsigned long Binding;
39
+ };
40
+
41
+
42
+
43
+
44
+
45
+ #endif // __ObjectBindings__H_
46
+
data/ext/cmain.cpp ADDED
@@ -0,0 +1,852 @@
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
+ /* 21Sep09: ruby 1.9 defines macros for common i/o functions that point to rb_w32_* implementations.
23
+ We need to undef the stat to fix a build failure in evma_send_file_data_to_connection.
24
+ See http://groups.google.com/group/eventmachine/browse_thread/thread/fc60d9bb738ffc71
25
+ */
26
+ #if defined(BUILD_FOR_RUBY) && defined(OS_WIN32)
27
+ #undef stat
28
+ #undef fstat
29
+ #endif
30
+
31
+ static EventMachine_t *EventMachine;
32
+ static int bUseEpoll = 0;
33
+ static int bUseKqueue = 0;
34
+
35
+ extern "C" void ensure_eventmachine (const char *caller = "unknown caller")
36
+ {
37
+ if (!EventMachine) {
38
+ const int err_size = 128;
39
+ char err_string[err_size];
40
+ snprintf (err_string, err_size, "eventmachine not initialized: %s", caller);
41
+ #ifdef BUILD_FOR_RUBY
42
+ rb_raise(rb_eRuntimeError, "%s", err_string);
43
+ #else
44
+ throw std::runtime_error (err_string);
45
+ #endif
46
+ }
47
+ }
48
+
49
+ /***********************
50
+ evma_initialize_library
51
+ ***********************/
52
+
53
+ extern "C" void evma_initialize_library (EMCallback cb)
54
+ {
55
+ // Probably a bad idea to mess with the signal mask of a process
56
+ // we're just being linked into.
57
+ //InstallSignalHandlers();
58
+ if (EventMachine)
59
+ #ifdef BUILD_FOR_RUBY
60
+ rb_raise(rb_eRuntimeError, "eventmachine already initialized: evma_initialize_library");
61
+ #else
62
+ throw std::runtime_error ("eventmachine already initialized: evma_initialize_library");
63
+ #endif
64
+ EventMachine = new EventMachine_t (cb);
65
+ if (bUseEpoll)
66
+ EventMachine->_UseEpoll();
67
+ if (bUseKqueue)
68
+ EventMachine->_UseKqueue();
69
+ }
70
+
71
+
72
+ /********************
73
+ evma_release_library
74
+ ********************/
75
+
76
+ extern "C" void evma_release_library()
77
+ {
78
+ ensure_eventmachine("evma_release_library");
79
+ delete EventMachine;
80
+ EventMachine = NULL;
81
+ }
82
+
83
+
84
+ /****************
85
+ evma_run_machine
86
+ ****************/
87
+
88
+ extern "C" void evma_run_machine()
89
+ {
90
+ ensure_eventmachine("evma_run_machine");
91
+ EventMachine->Run();
92
+ }
93
+
94
+
95
+ /**************************
96
+ evma_install_oneshot_timer
97
+ **************************/
98
+
99
+ extern "C" const unsigned long evma_install_oneshot_timer (int seconds)
100
+ {
101
+ ensure_eventmachine("evma_install_oneshot_timer");
102
+ return EventMachine->InstallOneshotTimer (seconds);
103
+ }
104
+
105
+
106
+ /**********************
107
+ evma_connect_to_server
108
+ **********************/
109
+
110
+ extern "C" const unsigned long evma_connect_to_server (const char *bind_addr, int bind_port, const char *server, int port)
111
+ {
112
+ ensure_eventmachine("evma_connect_to_server");
113
+ return EventMachine->ConnectToServer (bind_addr, bind_port, server, port);
114
+ }
115
+
116
+ /***************************
117
+ evma_connect_to_unix_server
118
+ ***************************/
119
+
120
+ extern "C" const unsigned long evma_connect_to_unix_server (const char *server)
121
+ {
122
+ ensure_eventmachine("evma_connect_to_unix_server");
123
+ return EventMachine->ConnectToUnixServer (server);
124
+ }
125
+
126
+ /**************
127
+ evma_attach_fd
128
+ **************/
129
+
130
+ extern "C" const unsigned long evma_attach_fd (int file_descriptor, int watch_mode)
131
+ {
132
+ ensure_eventmachine("evma_attach_fd");
133
+ return EventMachine->AttachFD (file_descriptor, watch_mode ? true : false);
134
+ }
135
+
136
+ /**************
137
+ evma_detach_fd
138
+ **************/
139
+
140
+ extern "C" int evma_detach_fd (const unsigned long binding)
141
+ {
142
+ ensure_eventmachine("evma_detach_fd");
143
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
144
+ if (ed)
145
+ return EventMachine->DetachFD (ed);
146
+ else
147
+ #ifdef BUILD_FOR_RUBY
148
+ rb_raise(rb_eRuntimeError, "invalid binding to detach");
149
+ #else
150
+ throw std::runtime_error ("invalid binding to detach");
151
+ #endif
152
+ return -1;
153
+ }
154
+
155
+ /************************
156
+ evma_get_file_descriptor
157
+ ************************/
158
+
159
+ extern "C" int evma_get_file_descriptor (const unsigned long binding)
160
+ {
161
+ ensure_eventmachine("evma_get_file_descriptor");
162
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
163
+ if (ed)
164
+ return ed->GetSocket();
165
+ else
166
+ #ifdef BUILD_FOR_RUBY
167
+ rb_raise(rb_eRuntimeError, "invalid binding to get_fd");
168
+ #else
169
+ throw std::runtime_error ("invalid binding to get_fd");
170
+ #endif
171
+ return -1;
172
+ }
173
+
174
+ /***********************
175
+ evma_is_notify_readable
176
+ ***********************/
177
+
178
+ extern "C" int evma_is_notify_readable (const unsigned long binding)
179
+ {
180
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
181
+ if (cd)
182
+ return cd->IsNotifyReadable() ? 1 : 0;
183
+ return -1;
184
+ }
185
+
186
+ /************************
187
+ evma_set_notify_readable
188
+ ************************/
189
+
190
+ extern "C" void evma_set_notify_readable (const unsigned long binding, int mode)
191
+ {
192
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
193
+ if (cd)
194
+ cd->SetNotifyReadable (mode ? true : false);
195
+ }
196
+
197
+ /***********************
198
+ evma_is_notify_writable
199
+ ***********************/
200
+
201
+ extern "C" int evma_is_notify_writable (const unsigned long binding)
202
+ {
203
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
204
+ if (cd)
205
+ return cd->IsNotifyWritable() ? 1 : 0;
206
+ return -1;
207
+ }
208
+
209
+ /************************
210
+ evma_set_notify_writable
211
+ ************************/
212
+
213
+ extern "C" void evma_set_notify_writable (const unsigned long binding, int mode)
214
+ {
215
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
216
+ if (cd)
217
+ cd->SetNotifyWritable (mode ? true : false);
218
+ }
219
+
220
+ /**********
221
+ evma_pause
222
+ **********/
223
+
224
+ extern "C" int evma_pause (const unsigned long binding)
225
+ {
226
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
227
+ if (cd)
228
+ return cd->Pause() ? 1 : 0;
229
+
230
+ return 0;
231
+ }
232
+
233
+ /***********
234
+ evma_resume
235
+ ***********/
236
+
237
+ extern "C" int evma_resume (const unsigned long binding)
238
+ {
239
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
240
+ if (cd)
241
+ return cd->Resume() ? 1 : 0;
242
+
243
+ return 0;
244
+ }
245
+
246
+ /**************
247
+ evma_is_paused
248
+ **************/
249
+
250
+ extern "C" int evma_is_paused (const unsigned long binding)
251
+ {
252
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
253
+ if (cd)
254
+ return cd->IsPaused() ? 1 : 0;
255
+
256
+ return 0;
257
+ }
258
+
259
+ /**********************
260
+ evma_create_tcp_server
261
+ **********************/
262
+
263
+ extern "C" const unsigned long evma_create_tcp_server (const char *address, int port)
264
+ {
265
+ ensure_eventmachine("evma_create_tcp_server");
266
+ return EventMachine->CreateTcpServer (address, port);
267
+ }
268
+
269
+ /******************************
270
+ evma_create_unix_domain_server
271
+ ******************************/
272
+
273
+ extern "C" const unsigned long evma_create_unix_domain_server (const char *filename)
274
+ {
275
+ ensure_eventmachine("evma_create_unix_domain_server");
276
+ return EventMachine->CreateUnixDomainServer (filename);
277
+ }
278
+
279
+ /*************************
280
+ evma_open_datagram_socket
281
+ *************************/
282
+
283
+ extern "C" const unsigned long evma_open_datagram_socket (const char *address, int port)
284
+ {
285
+ ensure_eventmachine("evma_open_datagram_socket");
286
+ return EventMachine->OpenDatagramSocket (address, port);
287
+ }
288
+
289
+ /******************
290
+ evma_open_keyboard
291
+ ******************/
292
+
293
+ extern "C" const unsigned long evma_open_keyboard()
294
+ {
295
+ ensure_eventmachine("evma_open_keyboard");
296
+ return EventMachine->OpenKeyboard();
297
+ }
298
+
299
+ /*******************
300
+ evma_watch_filename
301
+ *******************/
302
+
303
+ extern "C" const unsigned long evma_watch_filename (const char *fname)
304
+ {
305
+ ensure_eventmachine("evma_watch_filename");
306
+ return EventMachine->WatchFile(fname);
307
+ }
308
+
309
+ /*********************
310
+ evma_unwatch_filename
311
+ *********************/
312
+
313
+ extern "C" void evma_unwatch_filename (const unsigned long sig)
314
+ {
315
+ ensure_eventmachine("evma_unwatch_file");
316
+ EventMachine->UnwatchFile(sig);
317
+ }
318
+
319
+ /**************
320
+ evma_watch_pid
321
+ **************/
322
+
323
+ extern "C" const unsigned long evma_watch_pid (int pid)
324
+ {
325
+ ensure_eventmachine("evma_watch_pid");
326
+ return EventMachine->WatchPid(pid);
327
+ }
328
+
329
+ /****************
330
+ evma_unwatch_pid
331
+ ****************/
332
+
333
+ extern "C" void evma_unwatch_pid (const unsigned long sig)
334
+ {
335
+ ensure_eventmachine("evma_unwatch_pid");
336
+ EventMachine->UnwatchPid(sig);
337
+ }
338
+
339
+ /****************************
340
+ evma_send_data_to_connection
341
+ ****************************/
342
+
343
+ extern "C" int evma_send_data_to_connection (const unsigned long binding, const char *data, int data_length)
344
+ {
345
+ ensure_eventmachine("evma_send_data_to_connection");
346
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
347
+ if (ed)
348
+ return ed->SendOutboundData(data, data_length);
349
+ return -1;
350
+ }
351
+
352
+ /******************
353
+ evma_send_datagram
354
+ ******************/
355
+
356
+ extern "C" int evma_send_datagram (const unsigned long binding, const char *data, int data_length, const char *address, int port)
357
+ {
358
+ ensure_eventmachine("evma_send_datagram");
359
+ DatagramDescriptor *dd = dynamic_cast <DatagramDescriptor*> (Bindable_t::GetObject (binding));
360
+ if (dd)
361
+ return dd->SendOutboundDatagram(data, data_length, address, port);
362
+ return -1;
363
+ }
364
+
365
+
366
+ /*********************
367
+ evma_close_connection
368
+ *********************/
369
+
370
+ extern "C" void evma_close_connection (const unsigned long binding, int after_writing)
371
+ {
372
+ ensure_eventmachine("evma_close_connection");
373
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
374
+ if (ed)
375
+ ed->ScheduleClose (after_writing ? true : false);
376
+ }
377
+
378
+ /***********************************
379
+ evma_report_connection_error_status
380
+ ***********************************/
381
+
382
+ extern "C" int evma_report_connection_error_status (const unsigned long binding)
383
+ {
384
+ ensure_eventmachine("evma_report_connection_error_status");
385
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
386
+ if (ed)
387
+ return ed->ReportErrorStatus();
388
+ return -1;
389
+ }
390
+
391
+ /********************
392
+ evma_stop_tcp_server
393
+ ********************/
394
+
395
+ extern "C" void evma_stop_tcp_server (const unsigned long binding)
396
+ {
397
+ ensure_eventmachine("evma_stop_tcp_server");
398
+ AcceptorDescriptor::StopAcceptor (binding);
399
+ }
400
+
401
+
402
+ /*****************
403
+ evma_stop_machine
404
+ *****************/
405
+
406
+ extern "C" void evma_stop_machine()
407
+ {
408
+ ensure_eventmachine("evma_stop_machine");
409
+ EventMachine->ScheduleHalt();
410
+ }
411
+
412
+
413
+ /**************
414
+ evma_start_tls
415
+ **************/
416
+
417
+ extern "C" void evma_start_tls (const unsigned long binding)
418
+ {
419
+ ensure_eventmachine("evma_start_tls");
420
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
421
+ if (ed)
422
+ ed->StartTls();
423
+ }
424
+
425
+ /******************
426
+ evma_set_tls_parms
427
+ ******************/
428
+
429
+ extern "C" void evma_set_tls_parms (const unsigned long binding, const char *privatekey_filename, const char *certchain_filename, int verify_peer)
430
+ {
431
+ ensure_eventmachine("evma_set_tls_parms");
432
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
433
+ if (ed)
434
+ ed->SetTlsParms (privatekey_filename, certchain_filename, (verify_peer == 1 ? true : false));
435
+ }
436
+
437
+ /******************
438
+ evma_get_peer_cert
439
+ ******************/
440
+
441
+ #ifdef WITH_SSL
442
+ extern "C" X509 *evma_get_peer_cert (const unsigned long binding)
443
+ {
444
+ ensure_eventmachine("evma_get_peer_cert");
445
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
446
+ if (ed)
447
+ return ed->GetPeerCert();
448
+ return NULL;
449
+ }
450
+ #endif
451
+
452
+ /********************
453
+ evma_accept_ssl_peer
454
+ ********************/
455
+
456
+ #ifdef WITH_SSL
457
+ extern "C" void evma_accept_ssl_peer (const unsigned long binding)
458
+ {
459
+ ensure_eventmachine("evma_accept_ssl_peer");
460
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
461
+ if (cd)
462
+ cd->AcceptSslPeer();
463
+ }
464
+ #endif
465
+
466
+ /*****************
467
+ evma_get_peername
468
+ *****************/
469
+
470
+ extern "C" int evma_get_peername (const unsigned long binding, struct sockaddr *sa)
471
+ {
472
+ ensure_eventmachine("evma_get_peername");
473
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
474
+ if (ed) {
475
+ return ed->GetPeername (sa) ? 1 : 0;
476
+ }
477
+ else
478
+ return 0;
479
+ }
480
+
481
+ /*****************
482
+ evma_get_sockname
483
+ *****************/
484
+
485
+ extern "C" int evma_get_sockname (const unsigned long binding, struct sockaddr *sa)
486
+ {
487
+ ensure_eventmachine("evma_get_sockname");
488
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
489
+ if (ed) {
490
+ return ed->GetSockname (sa) ? 1 : 0;
491
+ }
492
+ else
493
+ return 0;
494
+ }
495
+
496
+ /***********************
497
+ evma_get_subprocess_pid
498
+ ***********************/
499
+
500
+ extern "C" int evma_get_subprocess_pid (const unsigned long binding, pid_t *pid)
501
+ {
502
+ ensure_eventmachine("evma_get_subprocess_pid");
503
+ #ifdef OS_UNIX
504
+ PipeDescriptor *pd = dynamic_cast <PipeDescriptor*> (Bindable_t::GetObject (binding));
505
+ if (pd) {
506
+ return pd->GetSubprocessPid (pid) ? 1 : 0;
507
+ }
508
+ else if (pid && EventMachine->SubprocessPid) {
509
+ *pid = EventMachine->SubprocessPid;
510
+ return 1;
511
+ }
512
+ else
513
+ return 0;
514
+ #else
515
+ return 0;
516
+ #endif
517
+ }
518
+
519
+ /**************************
520
+ evma_get_subprocess_status
521
+ **************************/
522
+
523
+ extern "C" int evma_get_subprocess_status (const unsigned long binding, int *status)
524
+ {
525
+ ensure_eventmachine("evma_get_subprocess_status");
526
+ if (status) {
527
+ *status = EventMachine->SubprocessExitStatus;
528
+ return 1;
529
+ }
530
+ else
531
+ return 0;
532
+ }
533
+
534
+ /*************************
535
+ evma_get_connection_count
536
+ *************************/
537
+
538
+ extern "C" int evma_get_connection_count()
539
+ {
540
+ ensure_eventmachine("evma_get_connection_count");
541
+ return EventMachine->GetConnectionCount();
542
+ }
543
+
544
+ /*********************
545
+ evma_signal_loopbreak
546
+ *********************/
547
+
548
+ extern "C" void evma_signal_loopbreak()
549
+ {
550
+ ensure_eventmachine("evma_signal_loopbreak");
551
+ EventMachine->SignalLoopBreaker();
552
+ }
553
+
554
+
555
+
556
+ /****************
557
+ evma__write_file
558
+ ****************/
559
+
560
+ extern "C" const unsigned long evma__write_file (const char *filename)
561
+ {
562
+ ensure_eventmachine("evma__write_file");
563
+ return EventMachine->_OpenFileForWriting (filename);
564
+ }
565
+
566
+
567
+ /********************************
568
+ evma_get_comm_inactivity_timeout
569
+ ********************************/
570
+
571
+ extern "C" float evma_get_comm_inactivity_timeout (const unsigned long binding)
572
+ {
573
+ ensure_eventmachine("evma_get_comm_inactivity_timeout");
574
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
575
+ if (ed) {
576
+ return ((float)ed->GetCommInactivityTimeout() / 1000);
577
+ }
578
+ else
579
+ return 0.0; //Perhaps this should be an exception. Access to an unknown binding.
580
+ }
581
+
582
+ /********************************
583
+ evma_set_comm_inactivity_timeout
584
+ ********************************/
585
+
586
+ extern "C" int evma_set_comm_inactivity_timeout (const unsigned long binding, float value)
587
+ {
588
+ ensure_eventmachine("evma_set_comm_inactivity_timeout");
589
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
590
+ if (ed) {
591
+ return ed->SetCommInactivityTimeout ((uint64_t)(value * 1000));
592
+ }
593
+ else
594
+ return 0; //Perhaps this should be an exception. Access to an unknown binding.
595
+ }
596
+
597
+
598
+ /********************************
599
+ evma_get_pending_connect_timeout
600
+ ********************************/
601
+
602
+ extern "C" float evma_get_pending_connect_timeout (const unsigned long binding)
603
+ {
604
+ ensure_eventmachine("evma_get_pending_connect_timeout");
605
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
606
+ if (ed) {
607
+ return ((float)ed->GetPendingConnectTimeout() / 1000);
608
+ }
609
+ else
610
+ return 0.0;
611
+ }
612
+
613
+
614
+ /********************************
615
+ evma_set_pending_connect_timeout
616
+ ********************************/
617
+
618
+ extern "C" int evma_set_pending_connect_timeout (const unsigned long binding, float value)
619
+ {
620
+ ensure_eventmachine("evma_set_pending_connect_timeout");
621
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
622
+ if (ed) {
623
+ return ed->SetPendingConnectTimeout ((uint64_t)(value * 1000));
624
+ }
625
+ else
626
+ return 0;
627
+ }
628
+
629
+
630
+ /**********************
631
+ evma_set_timer_quantum
632
+ **********************/
633
+
634
+ extern "C" void evma_set_timer_quantum (int interval)
635
+ {
636
+ ensure_eventmachine("evma_set_timer_quantum");
637
+ EventMachine->SetTimerQuantum (interval);
638
+ }
639
+
640
+
641
+ /************************
642
+ evma_get_max_timer_count
643
+ ************************/
644
+
645
+ extern "C" int evma_get_max_timer_count()
646
+ {
647
+ return EventMachine_t::GetMaxTimerCount();
648
+ }
649
+
650
+
651
+ /************************
652
+ evma_set_max_timer_count
653
+ ************************/
654
+
655
+ extern "C" void evma_set_max_timer_count (int ct)
656
+ {
657
+ // This may only be called if the reactor is not running.
658
+
659
+ if (EventMachine)
660
+ #ifdef BUILD_FOR_RUBY
661
+ rb_raise(rb_eRuntimeError, "eventmachine already initialized: evma_set_max_timer_count");
662
+ #else
663
+ throw std::runtime_error ("eventmachine already initialized: evma_set_max_timer_count");
664
+ #endif
665
+ EventMachine_t::SetMaxTimerCount (ct);
666
+ }
667
+
668
+ /******************
669
+ evma_setuid_string
670
+ ******************/
671
+
672
+ extern "C" void evma_setuid_string (const char *username)
673
+ {
674
+ // We do NOT need to be running an EM instance because this method is static.
675
+ EventMachine_t::SetuidString (username);
676
+ }
677
+
678
+
679
+ /**********
680
+ evma_popen
681
+ **********/
682
+
683
+ extern "C" const unsigned long evma_popen (char * const*cmd_strings)
684
+ {
685
+ ensure_eventmachine("evma_popen");
686
+ return EventMachine->Socketpair (cmd_strings);
687
+ }
688
+
689
+
690
+ /***************************
691
+ evma_get_outbound_data_size
692
+ ***************************/
693
+
694
+ extern "C" int evma_get_outbound_data_size (const unsigned long binding)
695
+ {
696
+ ensure_eventmachine("evma_get_outbound_data_size");
697
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
698
+ return ed ? ed->GetOutboundDataSize() : 0;
699
+ }
700
+
701
+
702
+ /**************
703
+ evma_set_epoll
704
+ **************/
705
+
706
+ extern "C" void evma_set_epoll (int use)
707
+ {
708
+ bUseEpoll = !!use;
709
+ }
710
+
711
+ /***************
712
+ evma_set_kqueue
713
+ ***************/
714
+
715
+ extern "C" void evma_set_kqueue (int use)
716
+ {
717
+ bUseKqueue = !!use;
718
+ }
719
+
720
+
721
+ /**********************
722
+ evma_set_rlimit_nofile
723
+ **********************/
724
+
725
+ extern "C" int evma_set_rlimit_nofile (int nofiles)
726
+ {
727
+ return EventMachine_t::SetRlimitNofile (nofiles);
728
+ }
729
+
730
+
731
+ /*********************************
732
+ evma_send_file_data_to_connection
733
+ *********************************/
734
+
735
+ extern "C" int evma_send_file_data_to_connection (const unsigned long binding, const char *filename)
736
+ {
737
+ /* This is a sugaring over send_data_to_connection that reads a file into a
738
+ * locally-allocated buffer, and sends the file data to the remote peer.
739
+ * Return the number of bytes written to the caller.
740
+ * TODO, needs to impose a limit on the file size. This is intended only for
741
+ * small files. (I don't know, maybe 8K or less.) For larger files, use interleaved
742
+ * I/O to avoid slowing the rest of the system down.
743
+ * TODO: we should return a code rather than barf, in case of file-not-found.
744
+ * TODO, does this compile on Windows?
745
+ * TODO, given that we want this to work only with small files, how about allocating
746
+ * the buffer on the stack rather than the heap?
747
+ *
748
+ * Modified 25Jul07. This now returns -1 on file-too-large; 0 for success, and a positive
749
+ * errno in case of other errors.
750
+ *
751
+ * Contributed by Kirk Haines.
752
+ */
753
+
754
+ char data[32*1024];
755
+ int r;
756
+
757
+ ensure_eventmachine("evma_send_file_data_to_connection");
758
+
759
+ int Fd = open (filename, O_RDONLY);
760
+
761
+ if (Fd < 0)
762
+ return errno;
763
+ // From here on, all early returns MUST close Fd.
764
+
765
+ struct stat st;
766
+ if (fstat (Fd, &st)) {
767
+ int e = errno;
768
+ close (Fd);
769
+ return e;
770
+ }
771
+
772
+ off_t filesize = st.st_size;
773
+ if (filesize <= 0) {
774
+ close (Fd);
775
+ return 0;
776
+ }
777
+ else if (filesize > (off_t) sizeof(data)) {
778
+ close (Fd);
779
+ return -1;
780
+ }
781
+
782
+
783
+ r = read (Fd, data, filesize);
784
+ if (r != filesize) {
785
+ int e = errno;
786
+ close (Fd);
787
+ return e;
788
+ }
789
+ evma_send_data_to_connection (binding, data, r);
790
+ close (Fd);
791
+
792
+ return 0;
793
+ }
794
+
795
+
796
+ /****************
797
+ evma_start_proxy
798
+ *****************/
799
+
800
+ extern "C" void evma_start_proxy (const unsigned long from, const unsigned long to, const unsigned long bufsize, const unsigned long length)
801
+ {
802
+ ensure_eventmachine("evma_start_proxy");
803
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (from));
804
+ if (ed)
805
+ ed->StartProxy(to, bufsize, length);
806
+ }
807
+
808
+
809
+ /***************
810
+ evma_stop_proxy
811
+ ****************/
812
+
813
+ extern "C" void evma_stop_proxy (const unsigned long from)
814
+ {
815
+ ensure_eventmachine("evma_stop_proxy");
816
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (from));
817
+ if (ed)
818
+ ed->StopProxy();
819
+ }
820
+
821
+
822
+ /***************************
823
+ evma_get_heartbeat_interval
824
+ ****************************/
825
+
826
+ extern "C" float evma_get_heartbeat_interval()
827
+ {
828
+ ensure_eventmachine("evma_get_heartbeat_interval");
829
+ return EventMachine->GetHeartbeatInterval();
830
+ }
831
+
832
+
833
+ /***************************
834
+ evma_set_heartbeat_interval
835
+ ****************************/
836
+
837
+ extern "C" int evma_set_heartbeat_interval(float interval)
838
+ {
839
+ ensure_eventmachine("evma_set_heartbeat_interval");
840
+ return EventMachine->SetHeartbeatInterval(interval);
841
+ }
842
+
843
+
844
+ /**************************
845
+ evma_get_current_loop_time
846
+ ***************************/
847
+
848
+ extern "C" uint64_t evma_get_current_loop_time()
849
+ {
850
+ ensure_eventmachine("evma_get_current_loop_time");
851
+ return EventMachine->GetCurrentLoopTime();
852
+ }