eventmachine-eventmachine 0.12.3

Sign up to get free protection for your applications and to get access to all the features.
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
+