eventmachine-eventmachine 0.12.3

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 (121) hide show
  1. data/Rakefile +169 -0
  2. data/docs/COPYING +60 -0
  3. data/docs/ChangeLog +183 -0
  4. data/docs/DEFERRABLES +138 -0
  5. data/docs/EPOLL +141 -0
  6. data/docs/GNU +281 -0
  7. data/docs/INSTALL +15 -0
  8. data/docs/KEYBOARD +38 -0
  9. data/docs/LEGAL +25 -0
  10. data/docs/LIGHTWEIGHT_CONCURRENCY +72 -0
  11. data/docs/PURE_RUBY +77 -0
  12. data/docs/README +74 -0
  13. data/docs/RELEASE_NOTES +96 -0
  14. data/docs/SMTP +9 -0
  15. data/docs/SPAWNED_PROCESSES +93 -0
  16. data/docs/TODO +10 -0
  17. data/ext/binder.cpp +126 -0
  18. data/ext/binder.h +48 -0
  19. data/ext/cmain.cpp +530 -0
  20. data/ext/cplusplus.cpp +172 -0
  21. data/ext/ed.cpp +1473 -0
  22. data/ext/ed.h +361 -0
  23. data/ext/em.cpp +1895 -0
  24. data/ext/em.h +170 -0
  25. data/ext/emwin.cpp +300 -0
  26. data/ext/emwin.h +94 -0
  27. data/ext/epoll.cpp +26 -0
  28. data/ext/epoll.h +25 -0
  29. data/ext/eventmachine.h +90 -0
  30. data/ext/eventmachine_cpp.h +94 -0
  31. data/ext/extconf.rb +150 -0
  32. data/ext/files.cpp +94 -0
  33. data/ext/files.h +65 -0
  34. data/ext/kb.cpp +368 -0
  35. data/ext/page.cpp +107 -0
  36. data/ext/page.h +51 -0
  37. data/ext/pipe.cpp +327 -0
  38. data/ext/project.h +119 -0
  39. data/ext/rubymain.cpp +683 -0
  40. data/ext/sigs.cpp +89 -0
  41. data/ext/sigs.h +32 -0
  42. data/ext/ssl.cpp +408 -0
  43. data/ext/ssl.h +86 -0
  44. data/java/src/com/rubyeventmachine/Application.java +196 -0
  45. data/java/src/com/rubyeventmachine/Connection.java +74 -0
  46. data/java/src/com/rubyeventmachine/ConnectionFactory.java +37 -0
  47. data/java/src/com/rubyeventmachine/DefaultConnectionFactory.java +46 -0
  48. data/java/src/com/rubyeventmachine/EmReactor.java +408 -0
  49. data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
  50. data/java/src/com/rubyeventmachine/EventableChannel.java +57 -0
  51. data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +171 -0
  52. data/java/src/com/rubyeventmachine/EventableSocketChannel.java +244 -0
  53. data/java/src/com/rubyeventmachine/PeriodicTimer.java +38 -0
  54. data/java/src/com/rubyeventmachine/Timer.java +54 -0
  55. data/java/src/com/rubyeventmachine/tests/ApplicationTest.java +108 -0
  56. data/java/src/com/rubyeventmachine/tests/ConnectTest.java +124 -0
  57. data/java/src/com/rubyeventmachine/tests/EMTest.java +80 -0
  58. data/java/src/com/rubyeventmachine/tests/TestDatagrams.java +53 -0
  59. data/java/src/com/rubyeventmachine/tests/TestServers.java +74 -0
  60. data/java/src/com/rubyeventmachine/tests/TestTimers.java +89 -0
  61. data/lib/em/deferrable.rb +208 -0
  62. data/lib/em/eventable.rb +39 -0
  63. data/lib/em/future.rb +62 -0
  64. data/lib/em/messages.rb +66 -0
  65. data/lib/em/processes.rb +68 -0
  66. data/lib/em/spawnable.rb +88 -0
  67. data/lib/em/streamer.rb +112 -0
  68. data/lib/eventmachine.rb +1763 -0
  69. data/lib/eventmachine_version.rb +31 -0
  70. data/lib/evma.rb +32 -0
  71. data/lib/evma/callback.rb +32 -0
  72. data/lib/evma/container.rb +75 -0
  73. data/lib/evma/factory.rb +77 -0
  74. data/lib/evma/protocol.rb +87 -0
  75. data/lib/evma/reactor.rb +48 -0
  76. data/lib/jeventmachine.rb +137 -0
  77. data/lib/pr_eventmachine.rb +1011 -0
  78. data/lib/protocols/buftok.rb +127 -0
  79. data/lib/protocols/header_and_content.rb +129 -0
  80. data/lib/protocols/httpcli2.rb +794 -0
  81. data/lib/protocols/httpclient.rb +270 -0
  82. data/lib/protocols/line_and_text.rb +122 -0
  83. data/lib/protocols/linetext2.rb +163 -0
  84. data/lib/protocols/postgres.rb +261 -0
  85. data/lib/protocols/saslauth.rb +179 -0
  86. data/lib/protocols/smtpclient.rb +308 -0
  87. data/lib/protocols/smtpserver.rb +556 -0
  88. data/lib/protocols/stomp.rb +130 -0
  89. data/lib/protocols/tcptest.rb +57 -0
  90. data/tasks/cpp.rake +77 -0
  91. data/tasks/project.rake +78 -0
  92. data/tasks/tests.rake +192 -0
  93. data/tests/test_attach.rb +66 -0
  94. data/tests/test_basic.rb +231 -0
  95. data/tests/test_defer.rb +47 -0
  96. data/tests/test_epoll.rb +161 -0
  97. data/tests/test_errors.rb +82 -0
  98. data/tests/test_eventables.rb +78 -0
  99. data/tests/test_exc.rb +58 -0
  100. data/tests/test_futures.rb +214 -0
  101. data/tests/test_hc.rb +218 -0
  102. data/tests/test_httpclient.rb +215 -0
  103. data/tests/test_httpclient2.rb +133 -0
  104. data/tests/test_kb.rb +61 -0
  105. data/tests/test_ltp.rb +192 -0
  106. data/tests/test_ltp2.rb +320 -0
  107. data/tests/test_next_tick.rb +102 -0
  108. data/tests/test_processes.rb +56 -0
  109. data/tests/test_pure.rb +129 -0
  110. data/tests/test_running.rb +47 -0
  111. data/tests/test_sasl.rb +74 -0
  112. data/tests/test_send_file.rb +245 -0
  113. data/tests/test_servers.rb +80 -0
  114. data/tests/test_smtpclient.rb +81 -0
  115. data/tests/test_smtpserver.rb +93 -0
  116. data/tests/test_spawn.rb +329 -0
  117. data/tests/test_ssl_args.rb +68 -0
  118. data/tests/test_timers.rb +146 -0
  119. data/tests/test_ud.rb +43 -0
  120. data/tests/testem.rb +31 -0
  121. metadata +197 -0
data/docs/TODO ADDED
@@ -0,0 +1,10 @@
1
+ $Id$
2
+
3
+ TODO List:
4
+
5
+ 12Aug06: Noticed by Don Stocks. A TCP connect-request that results
6
+ in a failed DNS resolution fires a fatal error back to user code.
7
+ Uuuuuugly. We should probably cause an unbind event to get fired
8
+ instead, and add some parameterization so the caller can detect
9
+ the nature of the failure.
10
+
data/ext/binder.cpp ADDED
@@ -0,0 +1,126 @@
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<string, Bindable_t*> Bindable_t::BindingBag;
26
+
27
+
28
+ /********************************
29
+ STATIC Bindable_t::CreateBinding
30
+ ********************************/
31
+
32
+ string Bindable_t::CreateBinding()
33
+ {
34
+ static int index = 0;
35
+ static string seed;
36
+
37
+ if ((index >= 1000000) || (seed.length() == 0)) {
38
+ #ifdef OS_UNIX
39
+ int fd = open (DEV_URANDOM, O_RDONLY);
40
+ if (fd < 0)
41
+ throw std::runtime_error ("No entropy device");
42
+
43
+ unsigned char u[16];
44
+ size_t r = read (fd, u, sizeof(u));
45
+ if (r < sizeof(u))
46
+ throw std::runtime_error ("Unable to read entropy device");
47
+
48
+ unsigned char *u1 = (unsigned char*)u;
49
+ char u2 [sizeof(u) * 2 + 1];
50
+
51
+ for (size_t i=0; i < sizeof(u); i++)
52
+ sprintf (u2 + (i * 2), "%02x", u1[i]);
53
+
54
+ seed = string (u2);
55
+ #endif
56
+
57
+
58
+ #ifdef OS_WIN32
59
+ UUID uuid;
60
+ UuidCreate (&uuid);
61
+ unsigned char *uuidstring = NULL;
62
+ UuidToString (&uuid, &uuidstring);
63
+ if (!uuidstring)
64
+ throw std::runtime_error ("Unable to read uuid");
65
+ seed = string ((const char*)uuidstring);
66
+
67
+ RpcStringFree (&uuidstring);
68
+ #endif
69
+
70
+ index = 0;
71
+
72
+
73
+ }
74
+
75
+ stringstream ss;
76
+ ss << seed << (++index);
77
+ return ss.str();
78
+ }
79
+
80
+
81
+ /*****************************
82
+ STATIC: Bindable_t::GetObject
83
+ *****************************/
84
+
85
+ Bindable_t *Bindable_t::GetObject (const char *binding)
86
+ {
87
+ string s (binding ? binding : "");
88
+ return GetObject (s);
89
+ }
90
+
91
+ /*****************************
92
+ STATIC: Bindable_t::GetObject
93
+ *****************************/
94
+
95
+ Bindable_t *Bindable_t::GetObject (const string &binding)
96
+ {
97
+ map<string, Bindable_t*>::const_iterator i = BindingBag.find (binding);
98
+ if (i != BindingBag.end())
99
+ return i->second;
100
+ else
101
+ return NULL;
102
+ }
103
+
104
+
105
+ /**********************
106
+ Bindable_t::Bindable_t
107
+ **********************/
108
+
109
+ Bindable_t::Bindable_t()
110
+ {
111
+ Binding = Bindable_t::CreateBinding();
112
+ BindingBag [Binding] = this;
113
+ }
114
+
115
+
116
+
117
+ /***********************
118
+ Bindable_t::~Bindable_t
119
+ ***********************/
120
+
121
+ Bindable_t::~Bindable_t()
122
+ {
123
+ BindingBag.erase (Binding);
124
+ }
125
+
126
+
data/ext/binder.h ADDED
@@ -0,0 +1,48 @@
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 string CreateBinding();
28
+ static Bindable_t *GetObject (const string&);
29
+ static Bindable_t *GetObject (const char*);
30
+ static map<string, Bindable_t*> BindingBag;
31
+
32
+ public:
33
+ Bindable_t();
34
+ virtual ~Bindable_t();
35
+
36
+ const string &GetBinding() {return Binding;}
37
+ const char *GetBindingChars() {return Binding.c_str();}
38
+
39
+ private:
40
+ string Binding;
41
+ };
42
+
43
+
44
+
45
+
46
+
47
+ #endif // __ObjectBindings__H_
48
+
data/ext/cmain.cpp ADDED
@@ -0,0 +1,530 @@
1
+ /*****************************************************************************
2
+
3
+ $Id$
4
+
5
+ File: cmain.cpp
6
+ Date: 06Apr06
7
+
8
+ Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
9
+ Gmail: blackhedd
10
+
11
+ This program is free software; you can redistribute it and/or modify
12
+ it under the terms of either: 1) the GNU General Public License
13
+ as published by the Free Software Foundation; either version 2 of the
14
+ License, or (at your option) any later version; or 2) Ruby's License.
15
+
16
+ See the file COPYING for complete licensing information.
17
+
18
+ *****************************************************************************/
19
+
20
+ #include "project.h"
21
+
22
+
23
+ static EventMachine_t *EventMachine;
24
+ static int bUseEpoll = 0;
25
+ static int bUseKqueue = 0;
26
+
27
+ extern "C" void ensure_eventmachine (const char *caller = "unknown caller")
28
+ {
29
+ if (!EventMachine) {
30
+ const int err_size = 128;
31
+ char err_string[err_size];
32
+ snprintf (err_string, err_size, "eventmachine not initialized: %s", caller);
33
+ throw std::runtime_error (err_string);
34
+ }
35
+ }
36
+
37
+ /***********************
38
+ evma_initialize_library
39
+ ***********************/
40
+
41
+ extern "C" void evma_initialize_library (void(*cb)(const char*, int, const char*, int))
42
+ {
43
+ // Probably a bad idea to mess with the signal mask of a process
44
+ // we're just being linked into.
45
+ //InstallSignalHandlers();
46
+ if (EventMachine)
47
+ throw std::runtime_error ("eventmachine already initialized: evma_initialize_library");
48
+ EventMachine = new EventMachine_t (cb);
49
+ if (bUseEpoll)
50
+ EventMachine->_UseEpoll();
51
+ if (bUseKqueue)
52
+ EventMachine->_UseKqueue();
53
+ }
54
+
55
+
56
+ /********************
57
+ evma_release_library
58
+ ********************/
59
+
60
+ extern "C" void evma_release_library()
61
+ {
62
+ ensure_eventmachine("evma_release_library");
63
+ delete EventMachine;
64
+ EventMachine = NULL;
65
+ }
66
+
67
+
68
+ /****************
69
+ evma_run_machine
70
+ ****************/
71
+
72
+ extern "C" void evma_run_machine()
73
+ {
74
+ ensure_eventmachine("evma_run_machine");
75
+ EventMachine->Run();
76
+ }
77
+
78
+
79
+ /**************************
80
+ evma_install_oneshot_timer
81
+ **************************/
82
+
83
+ extern "C" const char *evma_install_oneshot_timer (int seconds)
84
+ {
85
+ ensure_eventmachine("evma_install_oneshot_timer");
86
+ return EventMachine->InstallOneshotTimer (seconds);
87
+ }
88
+
89
+
90
+ /**********************
91
+ evma_connect_to_server
92
+ **********************/
93
+
94
+ extern "C" const char *evma_connect_to_server (const char *server, int port)
95
+ {
96
+ ensure_eventmachine("evma_connect_to_server");
97
+ return EventMachine->ConnectToServer (server, port);
98
+ }
99
+
100
+ /***************************
101
+ evma_connect_to_unix_server
102
+ ***************************/
103
+
104
+ extern "C" const char *evma_connect_to_unix_server (const char *server)
105
+ {
106
+ ensure_eventmachine("evma_connect_to_unix_server");
107
+ return EventMachine->ConnectToUnixServer (server);
108
+ }
109
+
110
+ /**************
111
+ evma_attach_fd
112
+ **************/
113
+
114
+ extern "C" const char *evma_attach_fd (int file_descriptor, int notify_readable, int notify_writable)
115
+ {
116
+ if (!EventMachine)
117
+ throw std::runtime_error ("not initialized");
118
+ return EventMachine->AttachFD (file_descriptor, (notify_readable ? true : false), (notify_writable ? true : false));
119
+ }
120
+
121
+ /**************
122
+ evma_detach_fd
123
+ **************/
124
+
125
+ extern "C" int evma_detach_fd (const char *binding)
126
+ {
127
+ if (!EventMachine)
128
+ throw std::runtime_error ("not initialized");
129
+
130
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
131
+ if (ed)
132
+ return EventMachine->DetachFD (ed);
133
+ else
134
+ throw std::runtime_error ("invalid binding to detach");
135
+ }
136
+
137
+ /**********************
138
+ evma_create_tcp_server
139
+ **********************/
140
+
141
+ extern "C" const char *evma_create_tcp_server (const char *address, int port)
142
+ {
143
+ ensure_eventmachine("evma_create_tcp_server");
144
+ return EventMachine->CreateTcpServer (address, port);
145
+ }
146
+
147
+ /******************************
148
+ evma_create_unix_domain_server
149
+ ******************************/
150
+
151
+ extern "C" const char *evma_create_unix_domain_server (const char *filename)
152
+ {
153
+ ensure_eventmachine("evma_create_unix_domain_server");
154
+ return EventMachine->CreateUnixDomainServer (filename);
155
+ }
156
+
157
+ /*************************
158
+ evma_open_datagram_socket
159
+ *************************/
160
+
161
+ extern "C" const char *evma_open_datagram_socket (const char *address, int port)
162
+ {
163
+ ensure_eventmachine("evma_open_datagram_socket");
164
+ return EventMachine->OpenDatagramSocket (address, port);
165
+ }
166
+
167
+ /******************
168
+ evma_open_keyboard
169
+ ******************/
170
+
171
+ extern "C" const char *evma_open_keyboard()
172
+ {
173
+ ensure_eventmachine("evma_open_keyboard");
174
+ return EventMachine->OpenKeyboard();
175
+ }
176
+
177
+
178
+
179
+ /****************************
180
+ evma_send_data_to_connection
181
+ ****************************/
182
+
183
+ extern "C" int evma_send_data_to_connection (const char *binding, const char *data, int data_length)
184
+ {
185
+ ensure_eventmachine("evma_send_data_to_connection");
186
+ return ConnectionDescriptor::SendDataToConnection (binding, data, data_length);
187
+ }
188
+
189
+ /******************
190
+ evma_send_datagram
191
+ ******************/
192
+
193
+ extern "C" int evma_send_datagram (const char *binding, const char *data, int data_length, const char *address, int port)
194
+ {
195
+ ensure_eventmachine("evma_send_datagram");
196
+ return DatagramDescriptor::SendDatagram (binding, data, data_length, address, port);
197
+ }
198
+
199
+
200
+ /*********************
201
+ evma_close_connection
202
+ *********************/
203
+
204
+ extern "C" void evma_close_connection (const char *binding, int after_writing)
205
+ {
206
+ ensure_eventmachine("evma_close_connection");
207
+ ConnectionDescriptor::CloseConnection (binding, (after_writing ? true : false));
208
+ }
209
+
210
+ /***********************************
211
+ evma_report_connection_error_status
212
+ ***********************************/
213
+
214
+ extern "C" int evma_report_connection_error_status (const char *binding)
215
+ {
216
+ ensure_eventmachine("evma_report_connection_error_status");
217
+ return ConnectionDescriptor::ReportErrorStatus (binding);
218
+ }
219
+
220
+ /********************
221
+ evma_stop_tcp_server
222
+ ********************/
223
+
224
+ extern "C" void evma_stop_tcp_server (const char *binding)
225
+ {
226
+ ensure_eventmachine("evma_stop_tcp_server");
227
+ AcceptorDescriptor::StopAcceptor (binding);
228
+ }
229
+
230
+
231
+ /*****************
232
+ evma_stop_machine
233
+ *****************/
234
+
235
+ extern "C" void evma_stop_machine()
236
+ {
237
+ ensure_eventmachine("evma_stop_machine");
238
+ EventMachine->ScheduleHalt();
239
+ }
240
+
241
+
242
+ /**************
243
+ evma_start_tls
244
+ **************/
245
+
246
+ extern "C" void evma_start_tls (const char *binding)
247
+ {
248
+ ensure_eventmachine("evma_start_tls");
249
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
250
+ if (ed)
251
+ ed->StartTls();
252
+ }
253
+
254
+ /******************
255
+ evma_set_tls_parms
256
+ ******************/
257
+
258
+ extern "C" void evma_set_tls_parms (const char *binding, const char *privatekey_filename, const char *certchain_filename)
259
+ {
260
+ ensure_eventmachine("evma_set_tls_parms");
261
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
262
+ if (ed)
263
+ ed->SetTlsParms (privatekey_filename, certchain_filename);
264
+ }
265
+
266
+
267
+ /*****************
268
+ evma_get_peername
269
+ *****************/
270
+
271
+ extern "C" int evma_get_peername (const char *binding, struct sockaddr *sa)
272
+ {
273
+ ensure_eventmachine("evma_get_peername");
274
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
275
+ if (ed) {
276
+ return ed->GetPeername (sa) ? 1 : 0;
277
+ }
278
+ else
279
+ return 0;
280
+ }
281
+
282
+ /*****************
283
+ evma_get_sockname
284
+ *****************/
285
+
286
+ extern "C" int evma_get_sockname (const char *binding, struct sockaddr *sa)
287
+ {
288
+ ensure_eventmachine("evma_get_sockname");
289
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
290
+ if (ed) {
291
+ return ed->GetSockname (sa) ? 1 : 0;
292
+ }
293
+ else
294
+ return 0;
295
+ }
296
+
297
+ /***********************
298
+ evma_get_subprocess_pid
299
+ ***********************/
300
+
301
+ extern "C" int evma_get_subprocess_pid (const char *binding, pid_t *pid)
302
+ {
303
+ ensure_eventmachine("evma_get_subprocess_pid");
304
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
305
+ if (ed) {
306
+ return ed->GetSubprocessPid (pid) ? 1 : 0;
307
+ }
308
+ else
309
+ return 0;
310
+ }
311
+
312
+ /**************************
313
+ evma_get_subprocess_status
314
+ **************************/
315
+
316
+ extern "C" int evma_get_subprocess_status (const char *binding, int *status)
317
+ {
318
+ ensure_eventmachine("evma_get_subprocess_status");
319
+ if (status) {
320
+ *status = EventMachine->SubprocessExitStatus;
321
+ return 1;
322
+ }
323
+ else
324
+ return 0;
325
+ }
326
+
327
+
328
+ /*********************
329
+ evma_signal_loopbreak
330
+ *********************/
331
+
332
+ extern "C" void evma_signal_loopbreak()
333
+ {
334
+ ensure_eventmachine("evma_signal_loopbreak");
335
+ EventMachine->SignalLoopBreaker();
336
+ }
337
+
338
+
339
+
340
+ /****************
341
+ evma__write_file
342
+ ****************/
343
+
344
+ extern "C" const char *evma__write_file (const char *filename)
345
+ {
346
+ ensure_eventmachine("evma__write_file");
347
+ return EventMachine->_OpenFileForWriting (filename);
348
+ }
349
+
350
+
351
+ /********************************
352
+ evma_get_comm_inactivity_timeout
353
+ ********************************/
354
+
355
+ extern "C" int evma_get_comm_inactivity_timeout (const char *binding, int *value)
356
+ {
357
+ ensure_eventmachine("evma_get_comm_inactivity_timeout");
358
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
359
+ if (ed) {
360
+ return ed->GetCommInactivityTimeout (value);
361
+ }
362
+ else
363
+ return 0; //Perhaps this should be an exception. Access to an unknown binding.
364
+ }
365
+
366
+ /********************************
367
+ evma_set_comm_inactivity_timeout
368
+ ********************************/
369
+
370
+ extern "C" int evma_set_comm_inactivity_timeout (const char *binding, int *value)
371
+ {
372
+ ensure_eventmachine("evma_set_comm_inactivity_timeout");
373
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
374
+ if (ed) {
375
+ return ed->SetCommInactivityTimeout (value);
376
+ }
377
+ else
378
+ return 0; //Perhaps this should be an exception. Access to an unknown binding.
379
+ }
380
+
381
+
382
+ /**********************
383
+ evma_set_timer_quantum
384
+ **********************/
385
+
386
+ extern "C" void evma_set_timer_quantum (int interval)
387
+ {
388
+ ensure_eventmachine("evma_set_timer_quantum");
389
+ EventMachine->SetTimerQuantum (interval);
390
+ }
391
+
392
+ /************************
393
+ evma_set_max_timer_count
394
+ ************************/
395
+
396
+ extern "C" void evma_set_max_timer_count (int ct)
397
+ {
398
+ // This may only be called if the reactor is not running.
399
+ if (EventMachine)
400
+ throw std::runtime_error ("eventmachine already initialized: evma_set_max_timer_count");
401
+ EventMachine_t::SetMaxTimerCount (ct);
402
+ }
403
+
404
+ /******************
405
+ evma_setuid_string
406
+ ******************/
407
+
408
+ extern "C" void evma_setuid_string (const char *username)
409
+ {
410
+ // We do NOT need to be running an EM instance because this method is static.
411
+ EventMachine_t::SetuidString (username);
412
+ }
413
+
414
+
415
+ /**********
416
+ evma_popen
417
+ **********/
418
+
419
+ extern "C" const char *evma_popen (char * const*cmd_strings)
420
+ {
421
+ ensure_eventmachine("evma_popen");
422
+ return EventMachine->Socketpair (cmd_strings);
423
+ }
424
+
425
+
426
+ /***************************
427
+ evma_get_outbound_data_size
428
+ ***************************/
429
+
430
+ extern "C" int evma_get_outbound_data_size (const char *binding)
431
+ {
432
+ ensure_eventmachine("evma_get_outbound_data_size");
433
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
434
+ return ed ? ed->GetOutboundDataSize() : 0;
435
+ }
436
+
437
+
438
+ /***********
439
+ evma__epoll
440
+ ***********/
441
+
442
+ extern "C" void evma__epoll()
443
+ {
444
+ bUseEpoll = 1;
445
+ }
446
+
447
+ /************
448
+ evma__kqueue
449
+ ************/
450
+
451
+ extern "C" void evma__kqueue()
452
+ {
453
+ bUseKqueue = 1;
454
+ }
455
+
456
+
457
+ /**********************
458
+ evma_set_rlimit_nofile
459
+ **********************/
460
+
461
+ extern "C" int evma_set_rlimit_nofile (int nofiles)
462
+ {
463
+ return EventMachine_t::SetRlimitNofile (nofiles);
464
+ }
465
+
466
+
467
+ /*********************************
468
+ evma_send_file_data_to_connection
469
+ *********************************/
470
+
471
+ extern "C" int evma_send_file_data_to_connection (const char *binding, const char *filename)
472
+ {
473
+ /* This is a sugaring over send_data_to_connection that reads a file into a
474
+ * locally-allocated buffer, and sends the file data to the remote peer.
475
+ * Return the number of bytes written to the caller.
476
+ * TODO, needs to impose a limit on the file size. This is intended only for
477
+ * small files. (I don't know, maybe 8K or less.) For larger files, use interleaved
478
+ * I/O to avoid slowing the rest of the system down.
479
+ * TODO: we should return a code rather than barf, in case of file-not-found.
480
+ * TODO, does this compile on Windows?
481
+ * TODO, given that we want this to work only with small files, how about allocating
482
+ * the buffer on the stack rather than the heap?
483
+ *
484
+ * Modified 25Jul07. This now returns -1 on file-too-large; 0 for success, and a positive
485
+ * errno in case of other errors.
486
+ *
487
+ /* Contributed by Kirk Haines.
488
+ */
489
+
490
+ char data[32*1024];
491
+ int r;
492
+
493
+ ensure_eventmachine("evma_send_file_data_to_connection");
494
+
495
+ int Fd = open (filename, O_RDONLY);
496
+
497
+ if (Fd < 0)
498
+ return errno;
499
+ // From here on, all early returns MUST close Fd.
500
+
501
+ struct stat st;
502
+ if (fstat (Fd, &st)) {
503
+ int e = errno;
504
+ close (Fd);
505
+ return e;
506
+ }
507
+
508
+ int filesize = st.st_size;
509
+ if (filesize <= 0) {
510
+ close (Fd);
511
+ return 0;
512
+ }
513
+ else if (filesize > sizeof(data)) {
514
+ close (Fd);
515
+ return -1;
516
+ }
517
+
518
+
519
+ r = read (Fd, data, filesize);
520
+ if (r != filesize) {
521
+ int e = errno;
522
+ close (Fd);
523
+ return e;
524
+ }
525
+ evma_send_data_to_connection (binding, data, r);
526
+ close (Fd);
527
+
528
+ return 0;
529
+ }
530
+