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/ext/project.h ADDED
@@ -0,0 +1,119 @@
1
+ /*****************************************************************************
2
+
3
+ $Id$
4
+
5
+ File: project.h
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
+
21
+ #ifndef __Project__H_
22
+ #define __Project__H_
23
+
24
+
25
+ #ifdef OS_WIN32
26
+ #pragma warning(disable:4786)
27
+ #endif
28
+
29
+ #include <iostream>
30
+ #include <map>
31
+ #include <set>
32
+ #include <vector>
33
+ #include <deque>
34
+ #include <string>
35
+ #include <sstream>
36
+ #include <stdexcept>
37
+
38
+
39
+ #ifdef OS_UNIX
40
+ #include <signal.h>
41
+ #include <netdb.h>
42
+ #include <time.h>
43
+ #include <sys/time.h>
44
+ #include <sys/types.h>
45
+ #include <sys/stat.h>
46
+ #include <sys/socket.h>
47
+ #include <sys/un.h>
48
+ #include <sys/resource.h>
49
+ #include <sys/wait.h>
50
+ #include <assert.h>
51
+ #include <unistd.h>
52
+ #include <fcntl.h>
53
+ #include <errno.h>
54
+ #include <netinet/in.h>
55
+ #include <netinet/tcp.h>
56
+ #include <arpa/inet.h>
57
+ #include <pwd.h>
58
+ typedef int SOCKET;
59
+ #define closesocket close
60
+ #define INVALID_SOCKET -1
61
+ #define SOCKET_ERROR -1
62
+ #ifdef OS_SOLARIS8
63
+ #include <strings.h>
64
+ #include <sys/un.h>
65
+ #ifndef AF_LOCAL
66
+ #define AF_LOCAL AF_UNIX
67
+ #endif
68
+ // INADDR_NONE is undefined on Solaris < 8. Thanks to Brett Eisenberg and Tim Pease.
69
+ #ifndef INADDR_NONE
70
+ #define INADDR_NONE ((unsigned long)-1)
71
+ #endif
72
+ #endif
73
+ #endif
74
+
75
+
76
+ #ifdef OS_WIN32
77
+ #define WIN32_LEAN_AND_MEAN
78
+ #include <windows.h>
79
+ #include <winsock2.h>
80
+ #include <ws2tcpip.h>
81
+ #include <rpc.h>
82
+ #include <fcntl.h>
83
+ #include <assert.h>
84
+ typedef int socklen_t;
85
+ typedef int pid_t;
86
+ #endif
87
+
88
+
89
+ using namespace std;
90
+
91
+ #ifdef WITH_SSL
92
+ #include <openssl/ssl.h>
93
+ #include <openssl/err.h>
94
+ #endif
95
+
96
+ #ifdef HAVE_EPOLL
97
+ #include <sys/epoll.h>
98
+ #endif
99
+
100
+ #ifdef HAVE_KQUEUE
101
+ #include <sys/event.h>
102
+ #include <sys/queue.h>
103
+ #endif
104
+
105
+ #include "binder.h"
106
+ #include "em.h"
107
+ #include "epoll.h"
108
+ #include "sigs.h"
109
+ #include "ed.h"
110
+ #include "files.h"
111
+ #include "page.h"
112
+ #include "ssl.h"
113
+ #include "eventmachine.h"
114
+ #include "eventmachine_cpp.h"
115
+
116
+
117
+
118
+
119
+ #endif // __Project__H_
data/ext/rubymain.cpp ADDED
@@ -0,0 +1,683 @@
1
+ /*****************************************************************************
2
+
3
+ $Id$
4
+
5
+ File: rubymain.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
+ #include "eventmachine.h"
22
+ #include <ruby.h>
23
+
24
+
25
+
26
+ /*******
27
+ Statics
28
+ *******/
29
+
30
+ static VALUE EmModule;
31
+ static VALUE EmConnection;
32
+
33
+ static VALUE Intern_at_signature;
34
+ static VALUE Intern_at_timers;
35
+ static VALUE Intern_at_conns;
36
+ static VALUE Intern_event_callback;
37
+ static VALUE Intern_run_deferred_callbacks;
38
+ static VALUE Intern_delete;
39
+ static VALUE Intern_call;
40
+ static VALUE Intern_receive_data;
41
+
42
+ static VALUE Intern_notify_readable;
43
+ static VALUE Intern_notify_writable;
44
+
45
+ /****************
46
+ t_event_callback
47
+ ****************/
48
+
49
+ static void event_callback (const char *a1, int a2, const char *a3, int a4)
50
+ {
51
+ if (a2 == EM_CONNECTION_READ) {
52
+ VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
53
+ VALUE q = rb_hash_aref (t, rb_str_new2(a1));
54
+ if (q == Qnil)
55
+ rb_raise (rb_eRuntimeError, "no connection");
56
+ rb_funcall (q, Intern_receive_data, 1, rb_str_new (a3, a4));
57
+ }
58
+ else if (a2 == EM_CONNECTION_NOTIFY_READABLE) {
59
+ VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
60
+ VALUE q = rb_hash_aref (t, rb_str_new2(a1));
61
+ if (q == Qnil)
62
+ rb_raise (rb_eRuntimeError, "no connection");
63
+ rb_funcall (q, Intern_notify_readable, 0);
64
+ }
65
+ else if (a2 == EM_CONNECTION_NOTIFY_WRITABLE) {
66
+ VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
67
+ VALUE q = rb_hash_aref (t, rb_str_new2(a1));
68
+ if (q == Qnil)
69
+ rb_raise (rb_eRuntimeError, "no connection");
70
+ rb_funcall (q, Intern_notify_writable, 0);
71
+ }
72
+ else if (a2 == EM_LOOPBREAK_SIGNAL) {
73
+ rb_funcall (EmModule, Intern_run_deferred_callbacks, 0);
74
+ }
75
+ else if (a2 == EM_TIMER_FIRED) {
76
+ VALUE t = rb_ivar_get (EmModule, Intern_at_timers);
77
+ VALUE q = rb_funcall (t, Intern_delete, 1, rb_str_new(a3, a4));
78
+ if (q == Qnil)
79
+ rb_raise (rb_eRuntimeError, "no timer");
80
+ rb_funcall (q, Intern_call, 0);
81
+ }
82
+ else
83
+ rb_funcall (EmModule, Intern_event_callback, 3, rb_str_new2(a1), (a2 << 1) | 1, rb_str_new(a3,a4));
84
+ }
85
+
86
+
87
+
88
+ /**************************
89
+ t_initialize_event_machine
90
+ **************************/
91
+
92
+ static VALUE t_initialize_event_machine (VALUE self)
93
+ {
94
+ evma_initialize_library (event_callback);
95
+ return Qnil;
96
+ }
97
+
98
+
99
+
100
+ /*****************************
101
+ t_run_machine_without_threads
102
+ *****************************/
103
+
104
+ static VALUE t_run_machine_without_threads (VALUE self)
105
+ {
106
+ evma_run_machine();
107
+ return Qnil;
108
+ }
109
+
110
+
111
+ /*******************
112
+ t_add_oneshot_timer
113
+ *******************/
114
+
115
+ static VALUE t_add_oneshot_timer (VALUE self, VALUE interval)
116
+ {
117
+ const char *f = evma_install_oneshot_timer (FIX2INT (interval));
118
+ if (!f || !*f)
119
+ rb_raise (rb_eRuntimeError, "no timer");
120
+ return rb_str_new2 (f);
121
+ }
122
+
123
+
124
+ /**************
125
+ t_start_server
126
+ **************/
127
+
128
+ static VALUE t_start_server (VALUE self, VALUE server, VALUE port)
129
+ {
130
+ const char *f = evma_create_tcp_server (StringValuePtr(server), FIX2INT(port));
131
+ if (!f || !*f)
132
+ rb_raise (rb_eRuntimeError, "no acceptor");
133
+ return rb_str_new2 (f);
134
+ }
135
+
136
+ /*************
137
+ t_stop_server
138
+ *************/
139
+
140
+ static VALUE t_stop_server (VALUE self, VALUE signature)
141
+ {
142
+ evma_stop_tcp_server (StringValuePtr (signature));
143
+ return Qnil;
144
+ }
145
+
146
+
147
+ /*******************
148
+ t_start_unix_server
149
+ *******************/
150
+
151
+ static VALUE t_start_unix_server (VALUE self, VALUE filename)
152
+ {
153
+ const char *f = evma_create_unix_domain_server (StringValuePtr(filename));
154
+ if (!f || !*f)
155
+ rb_raise (rb_eRuntimeError, "no unix-domain acceptor");
156
+ return rb_str_new2 (f);
157
+ }
158
+
159
+
160
+
161
+ /***********
162
+ t_send_data
163
+ ***********/
164
+
165
+ static VALUE t_send_data (VALUE self, VALUE signature, VALUE data, VALUE data_length)
166
+ {
167
+ int b = evma_send_data_to_connection (StringValuePtr (signature), StringValuePtr (data), FIX2INT (data_length));
168
+ return INT2NUM (b);
169
+ }
170
+
171
+
172
+ /***********
173
+ t_start_tls
174
+ ***********/
175
+
176
+ static VALUE t_start_tls (VALUE self, VALUE signature)
177
+ {
178
+ evma_start_tls (StringValuePtr (signature));
179
+ return Qnil;
180
+ }
181
+
182
+ /***************
183
+ t_set_tls_parms
184
+ ***************/
185
+
186
+ static VALUE t_set_tls_parms (VALUE self, VALUE signature, VALUE privkeyfile, VALUE certchainfile)
187
+ {
188
+ /* set_tls_parms takes a series of positional arguments for specifying such things
189
+ * as private keys and certificate chains.
190
+ * It's expected that the parameter list will grow as we add more supported features.
191
+ * ALL of these parameters are optional, and can be specified as empty or NULL strings.
192
+ */
193
+ evma_set_tls_parms (StringValuePtr (signature), StringValuePtr (privkeyfile), StringValuePtr (certchainfile) );
194
+ return Qnil;
195
+ }
196
+
197
+ /**************
198
+ t_get_peername
199
+ **************/
200
+
201
+ static VALUE t_get_peername (VALUE self, VALUE signature)
202
+ {
203
+ struct sockaddr s;
204
+ if (evma_get_peername (StringValuePtr (signature), &s)) {
205
+ return rb_str_new ((const char*)&s, sizeof(s));
206
+ }
207
+
208
+ return Qnil;
209
+ }
210
+
211
+ /**************
212
+ t_get_sockname
213
+ **************/
214
+
215
+ static VALUE t_get_sockname (VALUE self, VALUE signature)
216
+ {
217
+ struct sockaddr s;
218
+ if (evma_get_sockname (StringValuePtr (signature), &s)) {
219
+ return rb_str_new ((const char*)&s, sizeof(s));
220
+ }
221
+
222
+ return Qnil;
223
+ }
224
+
225
+ /********************
226
+ t_get_subprocess_pid
227
+ ********************/
228
+
229
+ static VALUE t_get_subprocess_pid (VALUE self, VALUE signature)
230
+ {
231
+ pid_t pid;
232
+ if (evma_get_subprocess_pid (StringValuePtr (signature), &pid)) {
233
+ return INT2NUM (pid);
234
+ }
235
+
236
+ return Qnil;
237
+ }
238
+
239
+ /***********************
240
+ t_get_subprocess_status
241
+ ***********************/
242
+
243
+ static VALUE t_get_subprocess_status (VALUE self, VALUE signature)
244
+ {
245
+ int status;
246
+ if (evma_get_subprocess_status (StringValuePtr (signature), &status)) {
247
+ return INT2NUM (status);
248
+ }
249
+
250
+ return Qnil;
251
+ }
252
+
253
+ /*****************************
254
+ t_get_comm_inactivity_timeout
255
+ *****************************/
256
+
257
+ static VALUE t_get_comm_inactivity_timeout (VALUE self, VALUE signature)
258
+ {
259
+ int timeout;
260
+ if (evma_get_comm_inactivity_timeout (StringValuePtr (signature), &timeout))
261
+ return INT2FIX (timeout);
262
+ return Qnil;
263
+ }
264
+
265
+ /*****************************
266
+ t_set_comm_inactivity_timeout
267
+ *****************************/
268
+
269
+ static VALUE t_set_comm_inactivity_timeout (VALUE self, VALUE signature, VALUE timeout)
270
+ {
271
+ int ti = FIX2INT (timeout);
272
+ if (evma_set_comm_inactivity_timeout (StringValuePtr (signature), &ti));
273
+ return Qtrue;
274
+ return Qnil;
275
+ }
276
+
277
+
278
+ /***************
279
+ t_send_datagram
280
+ ***************/
281
+
282
+ static VALUE t_send_datagram (VALUE self, VALUE signature, VALUE data, VALUE data_length, VALUE address, VALUE port)
283
+ {
284
+ int b = evma_send_datagram (StringValuePtr (signature), StringValuePtr (data), FIX2INT (data_length), StringValuePtr(address), FIX2INT(port));
285
+ return INT2NUM (b);
286
+ }
287
+
288
+
289
+ /******************
290
+ t_close_connection
291
+ ******************/
292
+
293
+ static VALUE t_close_connection (VALUE self, VALUE signature, VALUE after_writing)
294
+ {
295
+ evma_close_connection (StringValuePtr (signature), ((after_writing == Qtrue) ? 1 : 0));
296
+ return Qnil;
297
+ }
298
+
299
+ /********************************
300
+ t_report_connection_error_status
301
+ ********************************/
302
+
303
+ static VALUE t_report_connection_error_status (VALUE self, VALUE signature)
304
+ {
305
+ int b = evma_report_connection_error_status (StringValuePtr (signature));
306
+ return INT2NUM (b);
307
+ }
308
+
309
+
310
+
311
+ /****************
312
+ t_connect_server
313
+ ****************/
314
+
315
+ static VALUE t_connect_server (VALUE self, VALUE server, VALUE port)
316
+ {
317
+ // Avoid FIX2INT in this case, because it doesn't deal with type errors properly.
318
+ // Specifically, if the value of port comes in as a string rather than an integer,
319
+ // NUM2INT will throw a type error, but FIX2INT will generate garbage.
320
+
321
+ const char *f = evma_connect_to_server (StringValuePtr(server), NUM2INT(port));
322
+ if (!f || !*f)
323
+ rb_raise (rb_eRuntimeError, "no connection");
324
+ return rb_str_new2 (f);
325
+ }
326
+
327
+ /*********************
328
+ t_connect_unix_server
329
+ *********************/
330
+
331
+ static VALUE t_connect_unix_server (VALUE self, VALUE serversocket)
332
+ {
333
+ const char *f = evma_connect_to_unix_server (StringValuePtr(serversocket));
334
+ if (!f || !*f)
335
+ rb_raise (rb_eRuntimeError, "no connection");
336
+ return rb_str_new2 (f);
337
+ }
338
+
339
+ /***********
340
+ t_attach_fd
341
+ ***********/
342
+
343
+ static VALUE t_attach_fd (VALUE self, VALUE file_descriptor, VALUE read_mode, VALUE write_mode)
344
+ {
345
+ const char *f = evma_attach_fd (NUM2INT(file_descriptor), (read_mode == Qtrue) ? 1 : 0, (write_mode == Qtrue) ? 1 : 0);
346
+ if (!f || !*f)
347
+ rb_raise (rb_eRuntimeError, "no connection");
348
+ return rb_str_new2 (f);
349
+ }
350
+
351
+ /***********
352
+ t_detach_fd
353
+ ***********/
354
+
355
+ static VALUE t_detach_fd (VALUE self, VALUE signature)
356
+ {
357
+ return INT2NUM(evma_detach_fd (StringValuePtr(signature)));
358
+ }
359
+
360
+ /*****************
361
+ t_open_udp_socket
362
+ *****************/
363
+
364
+ static VALUE t_open_udp_socket (VALUE self, VALUE server, VALUE port)
365
+ {
366
+ const char *f = evma_open_datagram_socket (StringValuePtr(server), FIX2INT(port));
367
+ if (!f || !*f)
368
+ rb_raise (rb_eRuntimeError, "no datagram socket");
369
+ return rb_str_new2 (f);
370
+ }
371
+
372
+
373
+
374
+ /*****************
375
+ t_release_machine
376
+ *****************/
377
+
378
+ static VALUE t_release_machine (VALUE self)
379
+ {
380
+ evma_release_library();
381
+ return Qnil;
382
+ }
383
+
384
+
385
+ /******
386
+ t_stop
387
+ ******/
388
+
389
+ static VALUE t_stop (VALUE self)
390
+ {
391
+ evma_stop_machine();
392
+ return Qnil;
393
+ }
394
+
395
+ /******************
396
+ t_signal_loopbreak
397
+ ******************/
398
+
399
+ static VALUE t_signal_loopbreak (VALUE self)
400
+ {
401
+ evma_signal_loopbreak();
402
+ return Qnil;
403
+ }
404
+
405
+ /**************
406
+ t_library_type
407
+ **************/
408
+
409
+ static VALUE t_library_type (VALUE self)
410
+ {
411
+ return rb_eval_string (":extension");
412
+ }
413
+
414
+
415
+
416
+ /*******************
417
+ t_set_timer_quantum
418
+ *******************/
419
+
420
+ static VALUE t_set_timer_quantum (VALUE self, VALUE interval)
421
+ {
422
+ evma_set_timer_quantum (FIX2INT (interval));
423
+ return Qnil;
424
+ }
425
+
426
+ /********************
427
+ t_set_max_timer_count
428
+ ********************/
429
+
430
+ static VALUE t_set_max_timer_count (VALUE self, VALUE ct)
431
+ {
432
+ evma_set_max_timer_count (FIX2INT (ct));
433
+ return Qnil;
434
+ }
435
+
436
+ /***************
437
+ t_setuid_string
438
+ ***************/
439
+
440
+ static VALUE t_setuid_string (VALUE self, VALUE username)
441
+ {
442
+ evma_setuid_string (StringValuePtr (username));
443
+ return Qnil;
444
+ }
445
+
446
+
447
+
448
+ /*************
449
+ t__write_file
450
+ *************/
451
+
452
+ static VALUE t__write_file (VALUE self, VALUE filename)
453
+ {
454
+ const char *f = evma__write_file (StringValuePtr (filename));
455
+ if (!f || !*f)
456
+ rb_raise (rb_eRuntimeError, "file not opened");
457
+ return rb_str_new2 (f);
458
+ }
459
+
460
+ /**************
461
+ t_invoke_popen
462
+ **************/
463
+
464
+ static VALUE t_invoke_popen (VALUE self, VALUE cmd)
465
+ {
466
+ // 1.8.7+
467
+ #ifdef RARRAY_LEN
468
+ int len = RARRAY_LEN(cmd);
469
+ #else
470
+ int len = RARRAY (cmd)->len;
471
+ #endif
472
+ if (len > 98)
473
+ rb_raise (rb_eRuntimeError, "too many arguments to popen");
474
+ char *strings [100];
475
+ for (int i=0; i < len; i++) {
476
+ VALUE ix = INT2FIX (i);
477
+ VALUE s = rb_ary_aref (1, &ix, cmd);
478
+ strings[i] = StringValuePtr (s);
479
+ }
480
+ strings[len] = NULL;
481
+
482
+ const char *f = evma_popen (strings);
483
+ if (!f || !*f) {
484
+ char *err = strerror (errno);
485
+ char buf[100];
486
+ memset (buf, 0, sizeof(buf));
487
+ snprintf (buf, sizeof(buf)-1, "no popen: %s", (err?err:"???"));
488
+ rb_raise (rb_eRuntimeError, buf);
489
+ }
490
+ return rb_str_new2 (f);
491
+ }
492
+
493
+
494
+ /***************
495
+ t_read_keyboard
496
+ ***************/
497
+
498
+ static VALUE t_read_keyboard (VALUE self)
499
+ {
500
+ const char *f = evma_open_keyboard();
501
+ if (!f || !*f)
502
+ rb_raise (rb_eRuntimeError, "no keyboard reader");
503
+ return rb_str_new2 (f);
504
+ }
505
+
506
+
507
+ /********
508
+ t__epoll
509
+ ********/
510
+
511
+ static VALUE t__epoll (VALUE self)
512
+ {
513
+ // Temporary.
514
+ evma__epoll();
515
+ return Qnil;
516
+ }
517
+
518
+ /*********
519
+ t__kqueue
520
+ *********/
521
+
522
+ static VALUE t__kqueue (VALUE self)
523
+ {
524
+ // Temporary.
525
+ evma__kqueue();
526
+ return Qnil;
527
+ }
528
+
529
+
530
+ /****************
531
+ t_send_file_data
532
+ ****************/
533
+
534
+ static VALUE t_send_file_data (VALUE self, VALUE signature, VALUE filename)
535
+ {
536
+
537
+ /* The current implementation of evma_send_file_data_to_connection enforces a strict
538
+ * upper limit on the file size it will transmit (currently 32K). The function returns
539
+ * zero on success, -1 if the requested file exceeds its size limit, and a positive
540
+ * number for other errors.
541
+ * TODO: Positive return values are actually errno's, which is probably the wrong way to
542
+ * do this. For one thing it's ugly. For another, we can't be sure zero is never a real errno.
543
+ */
544
+
545
+ int b = evma_send_file_data_to_connection (StringValuePtr(signature), StringValuePtr(filename));
546
+ if (b == -1)
547
+ rb_raise(rb_eRuntimeError, "File too large. send_file_data() supports files under 32k.");
548
+ if (b > 0) {
549
+ char *err = strerror (b);
550
+ char buf[1024];
551
+ memset (buf, 0, sizeof(buf));
552
+ snprintf (buf, sizeof(buf)-1, ": %s %s", StringValuePtr(filename),(err?err:"???"));
553
+
554
+ rb_raise (rb_eIOError, buf);
555
+ }
556
+
557
+ return INT2NUM (0);
558
+ }
559
+
560
+
561
+ /*******************
562
+ t_set_rlimit_nofile
563
+ *******************/
564
+
565
+ static VALUE t_set_rlimit_nofile (VALUE self, VALUE arg)
566
+ {
567
+ arg = (NIL_P(arg)) ? -1 : NUM2INT (arg);
568
+ return INT2NUM (evma_set_rlimit_nofile (arg));
569
+ }
570
+
571
+ /***************************
572
+ conn_get_outbound_data_size
573
+ ***************************/
574
+
575
+ static VALUE conn_get_outbound_data_size (VALUE self)
576
+ {
577
+ VALUE sig = rb_ivar_get (self, Intern_at_signature);
578
+ return INT2NUM (evma_get_outbound_data_size (StringValuePtr(sig)));
579
+ }
580
+
581
+
582
+ /******************************
583
+ conn_associate_callback_target
584
+ ******************************/
585
+
586
+ static VALUE conn_associate_callback_target (VALUE self, VALUE sig)
587
+ {
588
+ // No-op for the time being.
589
+ return Qnil;
590
+ }
591
+
592
+
593
+ /*********************
594
+ Init_rubyeventmachine
595
+ *********************/
596
+
597
+ extern "C" void Init_rubyeventmachine()
598
+ {
599
+ // Tuck away some symbol values so we don't have to look 'em up every time we need 'em.
600
+ Intern_at_signature = rb_intern ("@signature");
601
+ Intern_at_timers = rb_intern ("@timers");
602
+ Intern_at_conns = rb_intern ("@conns");
603
+
604
+ Intern_event_callback = rb_intern ("event_callback");
605
+ Intern_run_deferred_callbacks = rb_intern ("run_deferred_callbacks");
606
+ Intern_delete = rb_intern ("delete");
607
+ Intern_call = rb_intern ("call");
608
+ Intern_receive_data = rb_intern ("receive_data");
609
+
610
+ Intern_notify_readable = rb_intern ("notify_readable");
611
+ Intern_notify_writable = rb_intern ("notify_writable");
612
+
613
+ // INCOMPLETE, we need to define class Connections inside module EventMachine
614
+ // run_machine and run_machine_without_threads are now identical.
615
+ // Must deprecate the without_threads variant.
616
+ EmModule = rb_define_module ("EventMachine");
617
+ EmConnection = rb_define_class_under (EmModule, "Connection", rb_cObject);
618
+
619
+ rb_define_class_under (EmModule, "ConnectionNotBound", rb_eException);
620
+ rb_define_class_under (EmModule, "NoHandlerForAcceptedConnection", rb_eException);
621
+ rb_define_class_under (EmModule, "UnknownTimerFired", rb_eException);
622
+
623
+ rb_define_module_function (EmModule, "initialize_event_machine", (VALUE(*)(...))t_initialize_event_machine, 0);
624
+ rb_define_module_function (EmModule, "run_machine", (VALUE(*)(...))t_run_machine_without_threads, 0);
625
+ rb_define_module_function (EmModule, "run_machine_without_threads", (VALUE(*)(...))t_run_machine_without_threads, 0);
626
+ rb_define_module_function (EmModule, "add_oneshot_timer", (VALUE(*)(...))t_add_oneshot_timer, 1);
627
+ rb_define_module_function (EmModule, "start_tcp_server", (VALUE(*)(...))t_start_server, 2);
628
+ rb_define_module_function (EmModule, "stop_tcp_server", (VALUE(*)(...))t_stop_server, 1);
629
+ rb_define_module_function (EmModule, "start_unix_server", (VALUE(*)(...))t_start_unix_server, 1);
630
+ rb_define_module_function (EmModule, "set_tls_parms", (VALUE(*)(...))t_set_tls_parms, 3);
631
+ rb_define_module_function (EmModule, "start_tls", (VALUE(*)(...))t_start_tls, 1);
632
+ rb_define_module_function (EmModule, "send_data", (VALUE(*)(...))t_send_data, 3);
633
+ rb_define_module_function (EmModule, "send_datagram", (VALUE(*)(...))t_send_datagram, 5);
634
+ rb_define_module_function (EmModule, "close_connection", (VALUE(*)(...))t_close_connection, 2);
635
+ rb_define_module_function (EmModule, "report_connection_error_status", (VALUE(*)(...))t_report_connection_error_status, 1);
636
+ rb_define_module_function (EmModule, "connect_server", (VALUE(*)(...))t_connect_server, 2);
637
+ rb_define_module_function (EmModule, "connect_unix_server", (VALUE(*)(...))t_connect_unix_server, 1);
638
+
639
+ rb_define_module_function (EmModule, "attach_fd", (VALUE (*)(...))t_attach_fd, 3);
640
+ rb_define_module_function (EmModule, "detach_fd", (VALUE (*)(...))t_detach_fd, 1);
641
+
642
+ rb_define_module_function (EmModule, "open_udp_socket", (VALUE(*)(...))t_open_udp_socket, 2);
643
+ rb_define_module_function (EmModule, "read_keyboard", (VALUE(*)(...))t_read_keyboard, 0);
644
+ rb_define_module_function (EmModule, "release_machine", (VALUE(*)(...))t_release_machine, 0);
645
+ rb_define_module_function (EmModule, "stop", (VALUE(*)(...))t_stop, 0);
646
+ rb_define_module_function (EmModule, "signal_loopbreak", (VALUE(*)(...))t_signal_loopbreak, 0);
647
+ rb_define_module_function (EmModule, "library_type", (VALUE(*)(...))t_library_type, 0);
648
+ rb_define_module_function (EmModule, "set_timer_quantum", (VALUE(*)(...))t_set_timer_quantum, 1);
649
+ rb_define_module_function (EmModule, "set_max_timer_count", (VALUE(*)(...))t_set_max_timer_count, 1);
650
+ rb_define_module_function (EmModule, "setuid_string", (VALUE(*)(...))t_setuid_string, 1);
651
+ rb_define_module_function (EmModule, "invoke_popen", (VALUE(*)(...))t_invoke_popen, 1);
652
+ rb_define_module_function (EmModule, "send_file_data", (VALUE(*)(...))t_send_file_data, 2);
653
+
654
+ // Provisional:
655
+ rb_define_module_function (EmModule, "_write_file", (VALUE(*)(...))t__write_file, 1);
656
+
657
+ rb_define_module_function (EmModule, "get_peername", (VALUE(*)(...))t_get_peername, 1);
658
+ rb_define_module_function (EmModule, "get_sockname", (VALUE(*)(...))t_get_sockname, 1);
659
+ rb_define_module_function (EmModule, "get_subprocess_pid", (VALUE(*)(...))t_get_subprocess_pid, 1);
660
+ rb_define_module_function (EmModule, "get_subprocess_status", (VALUE(*)(...))t_get_subprocess_status, 1);
661
+ rb_define_module_function (EmModule, "get_comm_inactivity_timeout", (VALUE(*)(...))t_get_comm_inactivity_timeout, 1);
662
+ rb_define_module_function (EmModule, "set_comm_inactivity_timeout", (VALUE(*)(...))t_set_comm_inactivity_timeout, 2);
663
+ rb_define_module_function (EmModule, "set_rlimit_nofile", (VALUE(*)(...))t_set_rlimit_nofile, 1);
664
+
665
+ // Temporary:
666
+ rb_define_module_function (EmModule, "epoll", (VALUE(*)(...))t__epoll, 0);
667
+ rb_define_module_function (EmModule, "kqueue", (VALUE(*)(...))t__kqueue, 0);
668
+
669
+ rb_define_method (EmConnection, "get_outbound_data_size", (VALUE(*)(...))conn_get_outbound_data_size, 0);
670
+ rb_define_method (EmConnection, "associate_callback_target", (VALUE(*)(...))conn_associate_callback_target, 1);
671
+
672
+ rb_define_const (EmModule, "TimerFired", INT2NUM(100));
673
+ rb_define_const (EmModule, "ConnectionData", INT2NUM(101));
674
+ rb_define_const (EmModule, "ConnectionUnbound", INT2NUM(102));
675
+ rb_define_const (EmModule, "ConnectionAccepted", INT2NUM(103));
676
+ rb_define_const (EmModule, "ConnectionCompleted", INT2NUM(104));
677
+ rb_define_const (EmModule, "LoopbreakSignalled", INT2NUM(105));
678
+
679
+ rb_define_const (EmModule, "ConnectionNotifyReadable", INT2NUM(106));
680
+ rb_define_const (EmModule, "ConnectionNotifyWritable", INT2NUM(107));
681
+
682
+ }
683
+