crusher-eventmachine 0.12.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }