eventmachine-le 1.1.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. data/.gitignore +21 -0
  2. data/.yardopts +7 -0
  3. data/GNU +281 -0
  4. data/LICENSE +60 -0
  5. data/README.md +80 -0
  6. data/Rakefile +19 -0
  7. data/eventmachine-le.gemspec +42 -0
  8. data/ext/binder.cpp +124 -0
  9. data/ext/binder.h +46 -0
  10. data/ext/cmain.cpp +841 -0
  11. data/ext/ed.cpp +1995 -0
  12. data/ext/ed.h +424 -0
  13. data/ext/em.cpp +2377 -0
  14. data/ext/em.h +243 -0
  15. data/ext/eventmachine.h +126 -0
  16. data/ext/extconf.rb +166 -0
  17. data/ext/fastfilereader/extconf.rb +94 -0
  18. data/ext/fastfilereader/mapper.cpp +214 -0
  19. data/ext/fastfilereader/mapper.h +59 -0
  20. data/ext/fastfilereader/rubymain.cpp +127 -0
  21. data/ext/kb.cpp +79 -0
  22. data/ext/page.cpp +107 -0
  23. data/ext/page.h +51 -0
  24. data/ext/pipe.cpp +347 -0
  25. data/ext/project.h +155 -0
  26. data/ext/rubymain.cpp +1269 -0
  27. data/ext/ssl.cpp +468 -0
  28. data/ext/ssl.h +94 -0
  29. data/lib/em/buftok.rb +110 -0
  30. data/lib/em/callback.rb +58 -0
  31. data/lib/em/channel.rb +64 -0
  32. data/lib/em/completion.rb +304 -0
  33. data/lib/em/connection.rb +728 -0
  34. data/lib/em/deferrable.rb +210 -0
  35. data/lib/em/deferrable/pool.rb +2 -0
  36. data/lib/em/file_watch.rb +73 -0
  37. data/lib/em/future.rb +61 -0
  38. data/lib/em/iterator.rb +313 -0
  39. data/lib/em/messages.rb +66 -0
  40. data/lib/em/pool.rb +151 -0
  41. data/lib/em/process_watch.rb +45 -0
  42. data/lib/em/processes.rb +123 -0
  43. data/lib/em/protocols.rb +37 -0
  44. data/lib/em/protocols/header_and_content.rb +138 -0
  45. data/lib/em/protocols/httpclient.rb +279 -0
  46. data/lib/em/protocols/httpclient2.rb +600 -0
  47. data/lib/em/protocols/line_and_text.rb +125 -0
  48. data/lib/em/protocols/line_protocol.rb +29 -0
  49. data/lib/em/protocols/linetext2.rb +161 -0
  50. data/lib/em/protocols/memcache.rb +331 -0
  51. data/lib/em/protocols/object_protocol.rb +46 -0
  52. data/lib/em/protocols/postgres3.rb +246 -0
  53. data/lib/em/protocols/saslauth.rb +175 -0
  54. data/lib/em/protocols/smtpclient.rb +365 -0
  55. data/lib/em/protocols/smtpserver.rb +663 -0
  56. data/lib/em/protocols/socks4.rb +66 -0
  57. data/lib/em/protocols/stomp.rb +202 -0
  58. data/lib/em/protocols/tcptest.rb +54 -0
  59. data/lib/em/queue.rb +71 -0
  60. data/lib/em/resolver.rb +195 -0
  61. data/lib/em/spawnable.rb +84 -0
  62. data/lib/em/streamer.rb +118 -0
  63. data/lib/em/threaded_resource.rb +90 -0
  64. data/lib/em/tick_loop.rb +85 -0
  65. data/lib/em/timers.rb +106 -0
  66. data/lib/em/version.rb +3 -0
  67. data/lib/eventmachine-le.rb +10 -0
  68. data/lib/eventmachine.rb +1548 -0
  69. data/rakelib/cpp.rake_example +77 -0
  70. data/rakelib/package.rake +98 -0
  71. data/rakelib/test.rake +8 -0
  72. data/tests/client.crt +31 -0
  73. data/tests/client.key +51 -0
  74. data/tests/em_test_helper.rb +143 -0
  75. data/tests/test_attach.rb +148 -0
  76. data/tests/test_basic.rb +294 -0
  77. data/tests/test_channel.rb +62 -0
  78. data/tests/test_completion.rb +177 -0
  79. data/tests/test_connection_count.rb +33 -0
  80. data/tests/test_defer.rb +18 -0
  81. data/tests/test_deferrable.rb +35 -0
  82. data/tests/test_epoll.rb +134 -0
  83. data/tests/test_error_handler.rb +38 -0
  84. data/tests/test_exc.rb +28 -0
  85. data/tests/test_file_watch.rb +65 -0
  86. data/tests/test_futures.rb +170 -0
  87. data/tests/test_get_sock_opt.rb +37 -0
  88. data/tests/test_handler_check.rb +35 -0
  89. data/tests/test_hc.rb +155 -0
  90. data/tests/test_httpclient.rb +190 -0
  91. data/tests/test_httpclient2.rb +128 -0
  92. data/tests/test_inactivity_timeout.rb +54 -0
  93. data/tests/test_ipv4.rb +125 -0
  94. data/tests/test_ipv6.rb +131 -0
  95. data/tests/test_iterator.rb +110 -0
  96. data/tests/test_kb.rb +34 -0
  97. data/tests/test_line_protocol.rb +33 -0
  98. data/tests/test_ltp.rb +138 -0
  99. data/tests/test_ltp2.rb +288 -0
  100. data/tests/test_next_tick.rb +104 -0
  101. data/tests/test_object_protocol.rb +36 -0
  102. data/tests/test_pause.rb +78 -0
  103. data/tests/test_pending_connect_timeout.rb +52 -0
  104. data/tests/test_pool.rb +196 -0
  105. data/tests/test_process_watch.rb +48 -0
  106. data/tests/test_processes.rb +133 -0
  107. data/tests/test_proxy_connection.rb +168 -0
  108. data/tests/test_pure.rb +88 -0
  109. data/tests/test_queue.rb +50 -0
  110. data/tests/test_resolver.rb +55 -0
  111. data/tests/test_running.rb +14 -0
  112. data/tests/test_sasl.rb +47 -0
  113. data/tests/test_send_file.rb +217 -0
  114. data/tests/test_servers.rb +33 -0
  115. data/tests/test_set_sock_opt.rb +41 -0
  116. data/tests/test_shutdown_hooks.rb +23 -0
  117. data/tests/test_smtpclient.rb +55 -0
  118. data/tests/test_smtpserver.rb +120 -0
  119. data/tests/test_spawn.rb +293 -0
  120. data/tests/test_ssl_args.rb +78 -0
  121. data/tests/test_ssl_methods.rb +48 -0
  122. data/tests/test_ssl_verify.rb +82 -0
  123. data/tests/test_threaded_resource.rb +55 -0
  124. data/tests/test_tick_loop.rb +59 -0
  125. data/tests/test_timers.rb +180 -0
  126. data/tests/test_ud.rb +8 -0
  127. data/tests/test_udp46.rb +53 -0
  128. data/tests/test_unbind_reason.rb +48 -0
  129. metadata +390 -0
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ GEMSPEC = Gem::Specification.load('eventmachine-le.gemspec')
3
+
4
+ require 'rake/clean'
5
+ task :clobber => :clean
6
+
7
+ desc "Build eventmachine-le, then run tests."
8
+ task :default => [:compile, :test]
9
+
10
+ desc 'Generate documentation'
11
+ begin
12
+ require 'yard'
13
+ YARD::Rake::YardocTask.new do |t|
14
+ t.files = ['lib/**/*.rb', '-', 'docs/*.md']
15
+ t.options = ['--main', 'README.md', '--no-private']
16
+ end
17
+ rescue LoadError
18
+ task :yard do puts "Please install yard first!"; end
19
+ end
@@ -0,0 +1,42 @@
1
+ # -*- encoding: utf-8 -*-
2
+ if RUBY_VERSION == '1.8.7'
3
+ $:.unshift File.expand_path("../lib", __FILE__)
4
+ require "em/version"
5
+ else
6
+ # Ruby 1.9.
7
+ require File.expand_path('../lib/em/version', __FILE__)
8
+ end
9
+
10
+ Gem::Specification.new do |s|
11
+ s.name = 'eventmachine-le'
12
+ s.version = EventMachine::VERSION
13
+ s.homepage = 'https://github.com/ibc/EventMachine-LE/'
14
+
15
+ s.authors = ["Francis Cianfrocca", "Aman Gupta", "hacked by Carsten Bormann and Inaki Baz Castillo"]
16
+ s.email = ["garbagecat10@gmail.com", "aman@tmm1.net", "cabo@tzi.org", "ibc@aliax.net"]
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.extensions = ["ext/extconf.rb", "ext/fastfilereader/extconf.rb"]
20
+
21
+ s.required_ruby_version = ">= 1.8.7"
22
+ s.add_development_dependency 'rake-compiler', '0.7.9'
23
+ s.add_development_dependency 'yard', ">= 0.7.2"
24
+ s.add_development_dependency 'bluecloth'
25
+
26
+ s.summary = 'EventMachine LE (Live Edition)'
27
+ s.description = "EventMachine-LE (Live Edition) is a branch of EventMachine (https://github.com/eventmachine/eventmachine).
28
+
29
+ This branch incorporates interesting pull requests that are not yet included in the mainline EventMachine repository. The maintainers of that version prefer to minimize change in order to keep the stability with already existing EventMachine deployments, which provides an impressive multi-platform base for IPv4 TCP servers (e.g., Web servers) that don't need good UDP or IPv6 support.
30
+
31
+ This dedication to stability is helpful for production use, but can also lead to ossification. The present \"Live Edition\" or \"Leading Edge\" branch has its focus on supporting a somewhat wider use, including new Web servers or protocols beyond the HTTP Web.
32
+
33
+ To provide even more focus, this branch is currently applying its energy towards Linux and Unix/BSD/OSX environments. Java reactor and pure Ruby reactor are for now removed in this branch, and Windows/Cygwin support is untested. This may very well change later, once interesting pull requests come in.
34
+
35
+ EventMachine-LE draws from a number of dormant pull requests on the mainline version of EventMachine. New proposals will also directly come to EventMachine-LE and will be included once they are tested.
36
+
37
+ This is not a \"development branch\", EventMachine-LE is ready for production, just beyond the focus of mainline EventMachine.
38
+ "
39
+
40
+ s.rdoc_options = ["--title", "EventMachine-LE", "--main", "README.md", "-x", "lib/em/version"]
41
+ s.extra_rdoc_files = ["README.md"] + `git ls-files`.split("\n")
42
+ end
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,841 @@
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
+ if (EventMachine)
56
+ #ifdef BUILD_FOR_RUBY
57
+ rb_raise(rb_eRuntimeError, "eventmachine already initialized: evma_initialize_library");
58
+ #else
59
+ throw std::runtime_error ("eventmachine already initialized: evma_initialize_library");
60
+ #endif
61
+ EventMachine = new EventMachine_t (cb);
62
+ if (bUseEpoll)
63
+ EventMachine->_UseEpoll();
64
+ if (bUseKqueue)
65
+ EventMachine->_UseKqueue();
66
+ }
67
+
68
+
69
+ /********************
70
+ evma_release_library
71
+ ********************/
72
+
73
+ extern "C" void evma_release_library()
74
+ {
75
+ ensure_eventmachine("evma_release_library");
76
+ delete EventMachine;
77
+ EventMachine = NULL;
78
+ }
79
+
80
+
81
+ /****************
82
+ evma_run_machine
83
+ ****************/
84
+
85
+ extern "C" void evma_run_machine()
86
+ {
87
+ ensure_eventmachine("evma_run_machine");
88
+ EventMachine->Run();
89
+ }
90
+
91
+
92
+ /**************************
93
+ evma_install_oneshot_timer
94
+ **************************/
95
+
96
+ extern "C" const unsigned long evma_install_oneshot_timer (int seconds)
97
+ {
98
+ ensure_eventmachine("evma_install_oneshot_timer");
99
+ return EventMachine->InstallOneshotTimer (seconds);
100
+ }
101
+
102
+
103
+ /**********************
104
+ evma_connect_to_server
105
+ **********************/
106
+
107
+ extern "C" const unsigned long evma_connect_to_server (const char *bind_addr, int bind_port, const char *server, int port)
108
+ {
109
+ ensure_eventmachine("evma_connect_to_server");
110
+ return EventMachine->ConnectToServer (bind_addr, bind_port, server, port);
111
+ }
112
+
113
+ /***************************
114
+ evma_connect_to_unix_server
115
+ ***************************/
116
+
117
+ extern "C" const unsigned long evma_connect_to_unix_server (const char *server)
118
+ {
119
+ ensure_eventmachine("evma_connect_to_unix_server");
120
+ return EventMachine->ConnectToUnixServer (server);
121
+ }
122
+
123
+ /**************
124
+ evma_attach_fd
125
+ **************/
126
+
127
+ extern "C" const unsigned long evma_attach_fd (int file_descriptor, int watch_mode)
128
+ {
129
+ ensure_eventmachine("evma_attach_fd");
130
+ return EventMachine->AttachFD (file_descriptor, watch_mode ? true : false);
131
+ }
132
+
133
+ /**************
134
+ evma_detach_fd
135
+ **************/
136
+
137
+ extern "C" int evma_detach_fd (const unsigned long binding)
138
+ {
139
+ ensure_eventmachine("evma_detach_fd");
140
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
141
+ if (ed)
142
+ return EventMachine->DetachFD (ed);
143
+ else
144
+ #ifdef BUILD_FOR_RUBY
145
+ rb_raise(rb_eRuntimeError, "invalid binding to detach");
146
+ #else
147
+ throw std::runtime_error ("invalid binding to detach");
148
+ #endif
149
+ return -1;
150
+ }
151
+
152
+ /*********************
153
+ evma_attach_server_fd
154
+ **********************/
155
+
156
+ extern "C" const unsigned long evma_attach_server_fd (int file_descriptor)
157
+ {
158
+ ensure_eventmachine("evma_attach_server_fd");
159
+ return EventMachine->AttachServerFD (file_descriptor);
160
+ }
161
+
162
+ /************************
163
+ evma_get_file_descriptor
164
+ ************************/
165
+
166
+ extern "C" int evma_get_file_descriptor (const unsigned long binding)
167
+ {
168
+ ensure_eventmachine("evma_get_file_descriptor");
169
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
170
+ if (ed)
171
+ return ed->GetSocket();
172
+ else
173
+ #ifdef BUILD_FOR_RUBY
174
+ rb_raise(rb_eRuntimeError, "invalid binding to get_fd");
175
+ #else
176
+ throw std::runtime_error ("invalid binding to get_fd");
177
+ #endif
178
+ return -1;
179
+ }
180
+
181
+ /***********************
182
+ evma_is_notify_readable
183
+ ***********************/
184
+
185
+ extern "C" int evma_is_notify_readable (const unsigned long binding)
186
+ {
187
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
188
+ if (cd)
189
+ return cd->IsNotifyReadable() ? 1 : 0;
190
+ return -1;
191
+ }
192
+
193
+ /************************
194
+ evma_set_notify_readable
195
+ ************************/
196
+
197
+ extern "C" void evma_set_notify_readable (const unsigned long binding, int mode)
198
+ {
199
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
200
+ if (cd)
201
+ cd->SetNotifyReadable (mode ? true : false);
202
+ }
203
+
204
+ /***********************
205
+ evma_is_notify_writable
206
+ ***********************/
207
+
208
+ extern "C" int evma_is_notify_writable (const unsigned long binding)
209
+ {
210
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
211
+ if (cd)
212
+ return cd->IsNotifyWritable() ? 1 : 0;
213
+ return -1;
214
+ }
215
+
216
+ /************************
217
+ evma_set_notify_writable
218
+ ************************/
219
+
220
+ extern "C" void evma_set_notify_writable (const unsigned long binding, int mode)
221
+ {
222
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
223
+ if (cd)
224
+ cd->SetNotifyWritable (mode ? true : false);
225
+ }
226
+
227
+ /************************
228
+ evma_set_error_handling
229
+ ************************/
230
+
231
+ extern "C" void evma_set_error_handling (const unsigned long binding, int mode)
232
+ {
233
+ DatagramDescriptor *cd = dynamic_cast <DatagramDescriptor*> (Bindable_t::GetObject (binding));
234
+ if (cd)
235
+ cd->SendErrorHandling = (DatagramDescriptor::ERRORHANDLINGTYPE)mode;
236
+ }
237
+
238
+ /**********
239
+ evma_pause
240
+ **********/
241
+
242
+ extern "C" int evma_pause (const unsigned long binding)
243
+ {
244
+ EventableDescriptor *cd = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
245
+ if (cd)
246
+ return cd->Pause() ? 1 : 0;
247
+
248
+ return 0;
249
+ }
250
+
251
+ /***********
252
+ evma_resume
253
+ ***********/
254
+
255
+ extern "C" int evma_resume (const unsigned long binding)
256
+ {
257
+ EventableDescriptor *cd = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
258
+ if (cd)
259
+ return cd->Resume() ? 1 : 0;
260
+
261
+ return 0;
262
+ }
263
+
264
+ /**************
265
+ evma_is_paused
266
+ **************/
267
+
268
+ extern "C" int evma_is_paused (const unsigned long binding)
269
+ {
270
+ EventableDescriptor *cd = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
271
+ if (cd)
272
+ return cd->IsPaused() ? 1 : 0;
273
+
274
+ return 0;
275
+ }
276
+
277
+ /************************
278
+ evma_num_close_scheduled
279
+ ************************/
280
+
281
+ extern "C" int evma_num_close_scheduled ()
282
+ {
283
+ return EventMachine->NumCloseScheduled;
284
+ }
285
+
286
+ /**********************
287
+ evma_create_tcp_server
288
+ **********************/
289
+
290
+ extern "C" const unsigned long evma_create_tcp_server (const char *address, int port)
291
+ {
292
+ ensure_eventmachine("evma_create_tcp_server");
293
+ return EventMachine->CreateTcpServer (address, port);
294
+ }
295
+
296
+ /******************************
297
+ evma_create_unix_domain_server
298
+ ******************************/
299
+
300
+ extern "C" const unsigned long evma_create_unix_domain_server (const char *filename)
301
+ {
302
+ ensure_eventmachine("evma_create_unix_domain_server");
303
+ return EventMachine->CreateUnixDomainServer (filename);
304
+ }
305
+
306
+ /*************************
307
+ evma_open_datagram_socket
308
+ *************************/
309
+
310
+ extern "C" const unsigned long evma_open_datagram_socket (const char *address, int port)
311
+ {
312
+ ensure_eventmachine("evma_open_datagram_socket");
313
+ return EventMachine->OpenDatagramSocket (address, port);
314
+ }
315
+
316
+ /******************
317
+ evma_open_keyboard
318
+ ******************/
319
+
320
+ extern "C" const unsigned long evma_open_keyboard()
321
+ {
322
+ ensure_eventmachine("evma_open_keyboard");
323
+ return EventMachine->OpenKeyboard();
324
+ }
325
+
326
+ /*******************
327
+ evma_watch_filename
328
+ *******************/
329
+
330
+ extern "C" const unsigned long evma_watch_filename (const char *fname)
331
+ {
332
+ ensure_eventmachine("evma_watch_filename");
333
+ return EventMachine->WatchFile(fname);
334
+ }
335
+
336
+ /*********************
337
+ evma_unwatch_filename
338
+ *********************/
339
+
340
+ extern "C" void evma_unwatch_filename (const unsigned long sig)
341
+ {
342
+ ensure_eventmachine("evma_unwatch_file");
343
+ EventMachine->UnwatchFile(sig);
344
+ }
345
+
346
+ /**************
347
+ evma_watch_pid
348
+ **************/
349
+
350
+ extern "C" const unsigned long evma_watch_pid (int pid)
351
+ {
352
+ ensure_eventmachine("evma_watch_pid");
353
+ return EventMachine->WatchPid(pid);
354
+ }
355
+
356
+ /****************
357
+ evma_unwatch_pid
358
+ ****************/
359
+
360
+ extern "C" void evma_unwatch_pid (const unsigned long sig)
361
+ {
362
+ ensure_eventmachine("evma_unwatch_pid");
363
+ EventMachine->UnwatchPid(sig);
364
+ }
365
+
366
+ /****************************
367
+ evma_send_data_to_connection
368
+ ****************************/
369
+
370
+ extern "C" int evma_send_data_to_connection (const unsigned long binding, const char *data, int data_length)
371
+ {
372
+ ensure_eventmachine("evma_send_data_to_connection");
373
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
374
+ if (ed)
375
+ return ed->SendOutboundData(data, data_length);
376
+ return -1;
377
+ }
378
+
379
+ /******************
380
+ evma_send_datagram
381
+ ******************/
382
+
383
+ extern "C" int evma_send_datagram (const unsigned long binding, const char *data, int data_length, const char *address, int port)
384
+ {
385
+ ensure_eventmachine("evma_send_datagram");
386
+ DatagramDescriptor *dd = dynamic_cast <DatagramDescriptor*> (Bindable_t::GetObject (binding));
387
+ if (dd)
388
+ return dd->SendOutboundDatagram(data, data_length, address, port);
389
+ return -1;
390
+ }
391
+
392
+
393
+ /*********************
394
+ evma_close_connection
395
+ *********************/
396
+
397
+ extern "C" void evma_close_connection (const unsigned long binding, int after_writing)
398
+ {
399
+ ensure_eventmachine("evma_close_connection");
400
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
401
+ if (ed)
402
+ ed->ScheduleClose (after_writing ? true : false);
403
+ }
404
+
405
+ /***********************************
406
+ evma_report_connection_error_status
407
+ ***********************************/
408
+
409
+ extern "C" int evma_report_connection_error_status (const unsigned long binding)
410
+ {
411
+ ensure_eventmachine("evma_report_connection_error_status");
412
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
413
+ if (ed)
414
+ return ed->ReportErrorStatus();
415
+ return -1;
416
+ }
417
+
418
+ /********************
419
+ evma_stop_tcp_server
420
+ ********************/
421
+
422
+ extern "C" void evma_stop_tcp_server (const unsigned long binding)
423
+ {
424
+ ensure_eventmachine("evma_stop_tcp_server");
425
+ AcceptorDescriptor::StopAcceptor (binding);
426
+ }
427
+
428
+
429
+ /*****************
430
+ evma_stop_machine
431
+ *****************/
432
+
433
+ extern "C" void evma_stop_machine()
434
+ {
435
+ ensure_eventmachine("evma_stop_machine");
436
+ EventMachine->ScheduleHalt();
437
+ }
438
+
439
+
440
+ /**************
441
+ evma_start_tls
442
+ **************/
443
+
444
+ extern "C" void evma_start_tls (const unsigned long binding)
445
+ {
446
+ ensure_eventmachine("evma_start_tls");
447
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
448
+ if (ed)
449
+ ed->StartTls();
450
+ }
451
+
452
+ /******************
453
+ evma_set_tls_parms
454
+ ******************/
455
+
456
+ extern "C" void evma_set_tls_parms (const unsigned long binding, const char *privatekey_filename, const char *certchain_filename, int verify_peer)
457
+ {
458
+ ensure_eventmachine("evma_set_tls_parms");
459
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
460
+ if (ed)
461
+ ed->SetTlsParms (privatekey_filename, certchain_filename, (verify_peer == 1 ? true : false));
462
+ }
463
+
464
+ /******************
465
+ evma_get_peer_cert
466
+ ******************/
467
+
468
+ #ifdef WITH_SSL
469
+ extern "C" X509 *evma_get_peer_cert (const unsigned long binding)
470
+ {
471
+ ensure_eventmachine("evma_get_peer_cert");
472
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
473
+ if (ed)
474
+ return ed->GetPeerCert();
475
+ return NULL;
476
+ }
477
+ #endif
478
+
479
+ /********************
480
+ evma_accept_ssl_peer
481
+ ********************/
482
+
483
+ #ifdef WITH_SSL
484
+ extern "C" void evma_accept_ssl_peer (const unsigned long binding)
485
+ {
486
+ ensure_eventmachine("evma_accept_ssl_peer");
487
+ ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
488
+ if (cd)
489
+ cd->AcceptSslPeer();
490
+ }
491
+ #endif
492
+
493
+ /*****************
494
+ evma_get_peername
495
+ *****************/
496
+
497
+ extern "C" int evma_get_peername (const unsigned long binding, struct sockaddr_storage *sa, socklen_t *len)
498
+ {
499
+ ensure_eventmachine("evma_get_peername");
500
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
501
+ if (ed) {
502
+ return ed->GetPeername (sa, len) ? 1 : 0;
503
+ }
504
+ else
505
+ return 0;
506
+ }
507
+
508
+ /*****************
509
+ evma_get_sockname
510
+ *****************/
511
+
512
+ extern "C" int evma_get_sockname (const unsigned long binding, struct sockaddr_storage *sa, socklen_t *len)
513
+ {
514
+ ensure_eventmachine("evma_get_sockname");
515
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
516
+ if (ed) {
517
+ return ed->GetSockname (sa, len) ? 1 : 0;
518
+ }
519
+ else
520
+ return 0;
521
+ }
522
+
523
+ /***********************
524
+ evma_get_subprocess_pid
525
+ ***********************/
526
+
527
+ extern "C" int evma_get_subprocess_pid (const unsigned long binding, pid_t *pid)
528
+ {
529
+ ensure_eventmachine("evma_get_subprocess_pid");
530
+ #ifdef OS_UNIX
531
+ PipeDescriptor *pd = dynamic_cast <PipeDescriptor*> (Bindable_t::GetObject (binding));
532
+ if (pd) {
533
+ return pd->GetSubprocessPid (pid) ? 1 : 0;
534
+ }
535
+ else if (pid && EventMachine->SubprocessPid) {
536
+ *pid = EventMachine->SubprocessPid;
537
+ return 1;
538
+ }
539
+ else
540
+ return 0;
541
+ #else
542
+ return 0;
543
+ #endif
544
+ }
545
+
546
+ /**************************
547
+ evma_get_subprocess_status
548
+ **************************/
549
+
550
+ extern "C" int evma_get_subprocess_status (const unsigned long binding, int *status)
551
+ {
552
+ ensure_eventmachine("evma_get_subprocess_status");
553
+ if (status) {
554
+ *status = EventMachine->SubprocessExitStatus;
555
+ return 1;
556
+ }
557
+ else
558
+ return 0;
559
+ }
560
+
561
+ /*************************
562
+ evma_get_connection_count
563
+ *************************/
564
+
565
+ extern "C" int evma_get_connection_count()
566
+ {
567
+ ensure_eventmachine("evma_get_connection_count");
568
+ return EventMachine->GetConnectionCount();
569
+ }
570
+
571
+ /*********************
572
+ evma_signal_loopbreak
573
+ *********************/
574
+
575
+ extern "C" void evma_signal_loopbreak()
576
+ {
577
+ ensure_eventmachine("evma_signal_loopbreak");
578
+ EventMachine->SignalLoopBreaker();
579
+ }
580
+
581
+
582
+
583
+ /********************************
584
+ evma_get_comm_inactivity_timeout
585
+ ********************************/
586
+
587
+ extern "C" float evma_get_comm_inactivity_timeout (const unsigned long binding)
588
+ {
589
+ ensure_eventmachine("evma_get_comm_inactivity_timeout");
590
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
591
+ if (ed) {
592
+ return ((float)ed->GetCommInactivityTimeout() / 1000);
593
+ }
594
+ else
595
+ return 0.0; //Perhaps this should be an exception. Access to an unknown binding.
596
+ }
597
+
598
+ /********************************
599
+ evma_set_comm_inactivity_timeout
600
+ ********************************/
601
+
602
+ extern "C" int evma_set_comm_inactivity_timeout (const unsigned long binding, float value)
603
+ {
604
+ ensure_eventmachine("evma_set_comm_inactivity_timeout");
605
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
606
+ if (ed) {
607
+ return ed->SetCommInactivityTimeout ((uint64_t)(value * 1000));
608
+ }
609
+ else
610
+ return 0; //Perhaps this should be an exception. Access to an unknown binding.
611
+ }
612
+
613
+
614
+ /********************************
615
+ evma_get_pending_connect_timeout
616
+ ********************************/
617
+
618
+ extern "C" float evma_get_pending_connect_timeout (const unsigned long binding)
619
+ {
620
+ ensure_eventmachine("evma_get_pending_connect_timeout");
621
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
622
+ if (ed) {
623
+ return ((float)ed->GetPendingConnectTimeout() / 1000);
624
+ }
625
+ else
626
+ return 0.0;
627
+ }
628
+
629
+
630
+ /********************************
631
+ evma_set_pending_connect_timeout
632
+ ********************************/
633
+
634
+ extern "C" int evma_set_pending_connect_timeout (const unsigned long binding, float value)
635
+ {
636
+ ensure_eventmachine("evma_set_pending_connect_timeout");
637
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
638
+ if (ed) {
639
+ return ed->SetPendingConnectTimeout ((uint64_t)(value * 1000));
640
+ }
641
+ else
642
+ return 0;
643
+ }
644
+
645
+
646
+ /**********************
647
+ evma_set_timer_quantum
648
+ **********************/
649
+
650
+ extern "C" void evma_set_timer_quantum (int interval)
651
+ {
652
+ ensure_eventmachine("evma_set_timer_quantum");
653
+ EventMachine->SetTimerQuantum (interval);
654
+ }
655
+
656
+
657
+ /******************
658
+ evma_setuid_string
659
+ ******************/
660
+
661
+ extern "C" void evma_setuid_string (const char *username)
662
+ {
663
+ // We do NOT need to be running an EM instance because this method is static.
664
+ EventMachine_t::SetuidString (username);
665
+ }
666
+
667
+
668
+ /**********
669
+ evma_popen
670
+ **********/
671
+
672
+ extern "C" const unsigned long evma_popen (char * const*cmd_strings)
673
+ {
674
+ ensure_eventmachine("evma_popen");
675
+ return EventMachine->Socketpair (cmd_strings);
676
+ }
677
+
678
+
679
+ /***************************
680
+ evma_get_outbound_data_size
681
+ ***************************/
682
+
683
+ extern "C" int evma_get_outbound_data_size (const unsigned long binding)
684
+ {
685
+ ensure_eventmachine("evma_get_outbound_data_size");
686
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
687
+ return ed ? ed->GetOutboundDataSize() : 0;
688
+ }
689
+
690
+
691
+ /**************
692
+ evma_set_epoll
693
+ **************/
694
+
695
+ extern "C" void evma_set_epoll (int use)
696
+ {
697
+ bUseEpoll = !!use;
698
+ }
699
+
700
+ /***************
701
+ evma_set_kqueue
702
+ ***************/
703
+
704
+ extern "C" void evma_set_kqueue (int use)
705
+ {
706
+ bUseKqueue = !!use;
707
+ }
708
+
709
+
710
+ /**********************
711
+ evma_set_rlimit_nofile
712
+ **********************/
713
+
714
+ extern "C" int evma_set_rlimit_nofile (int nofiles)
715
+ {
716
+ return EventMachine_t::SetRlimitNofile (nofiles);
717
+ }
718
+
719
+
720
+ /*********************************
721
+ evma_send_file_data_to_connection
722
+ *********************************/
723
+
724
+ extern "C" int evma_send_file_data_to_connection (const unsigned long binding, const char *filename)
725
+ {
726
+ /* This is a sugaring over send_data_to_connection that reads a file into a
727
+ * locally-allocated buffer, and sends the file data to the remote peer.
728
+ * Return the number of bytes written to the caller.
729
+ * TODO, needs to impose a limit on the file size. This is intended only for
730
+ * small files. (I don't know, maybe 8K or less.) For larger files, use interleaved
731
+ * I/O to avoid slowing the rest of the system down.
732
+ * TODO: we should return a code rather than barf, in case of file-not-found.
733
+ * TODO, does this compile on Windows?
734
+ * TODO, given that we want this to work only with small files, how about allocating
735
+ * the buffer on the stack rather than the heap?
736
+ *
737
+ * Modified 25Jul07. This now returns -1 on file-too-large; 0 for success, and a positive
738
+ * errno in case of other errors.
739
+ *
740
+ * Contributed by Kirk Haines.
741
+ */
742
+
743
+ char data[32*1024];
744
+ int r;
745
+
746
+ ensure_eventmachine("evma_send_file_data_to_connection");
747
+
748
+ int Fd = open (filename, O_RDONLY);
749
+
750
+ if (Fd < 0)
751
+ return errno;
752
+ // From here on, all early returns MUST close Fd.
753
+
754
+ struct stat st;
755
+ if (fstat (Fd, &st)) {
756
+ int e = errno;
757
+ close (Fd);
758
+ return e;
759
+ }
760
+
761
+ off_t filesize = st.st_size;
762
+ if (filesize <= 0) {
763
+ close (Fd);
764
+ return 0;
765
+ }
766
+ else if (filesize > (off_t) sizeof(data)) {
767
+ close (Fd);
768
+ return -1;
769
+ }
770
+
771
+
772
+ r = read (Fd, data, filesize);
773
+ if (r != filesize) {
774
+ int e = errno;
775
+ close (Fd);
776
+ return e;
777
+ }
778
+ evma_send_data_to_connection (binding, data, r);
779
+ close (Fd);
780
+
781
+ return 0;
782
+ }
783
+
784
+
785
+ /****************
786
+ evma_start_proxy
787
+ *****************/
788
+
789
+ extern "C" void evma_start_proxy (const unsigned long from, const unsigned long to, const unsigned long bufsize, const unsigned long length)
790
+ {
791
+ ensure_eventmachine("evma_start_proxy");
792
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (from));
793
+ if (ed)
794
+ ed->StartProxy(to, bufsize, length);
795
+ }
796
+
797
+
798
+ /***************
799
+ evma_stop_proxy
800
+ ****************/
801
+
802
+ extern "C" void evma_stop_proxy (const unsigned long from)
803
+ {
804
+ ensure_eventmachine("evma_stop_proxy");
805
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (from));
806
+ if (ed)
807
+ ed->StopProxy();
808
+ }
809
+
810
+
811
+ /***************************
812
+ evma_get_heartbeat_interval
813
+ ****************************/
814
+
815
+ extern "C" float evma_get_heartbeat_interval()
816
+ {
817
+ ensure_eventmachine("evma_get_heartbeat_interval");
818
+ return EventMachine->GetHeartbeatInterval();
819
+ }
820
+
821
+
822
+ /***************************
823
+ evma_set_heartbeat_interval
824
+ ****************************/
825
+
826
+ extern "C" int evma_set_heartbeat_interval(float interval)
827
+ {
828
+ ensure_eventmachine("evma_set_heartbeat_interval");
829
+ return EventMachine->SetHeartbeatInterval(interval);
830
+ }
831
+
832
+
833
+ /**************************
834
+ evma_get_current_loop_time
835
+ ***************************/
836
+
837
+ extern "C" uint64_t evma_get_current_loop_time()
838
+ {
839
+ ensure_eventmachine("evma_get_current_loop_time");
840
+ return EventMachine->GetCurrentLoopTime();
841
+ }