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/ext/project.h ADDED
@@ -0,0 +1,155 @@
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
+ #include <string.h>
59
+ typedef int SOCKET;
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 /* OS_SOLARIS8 */
73
+
74
+ #ifdef _AIX
75
+ #include <strings.h>
76
+ #ifndef AF_LOCAL
77
+ #define AF_LOCAL AF_UNIX
78
+ #endif
79
+ #endif /* _AIX */
80
+
81
+ #endif /* OS_UNIX */
82
+
83
+ #ifdef OS_WIN32
84
+ // 21Sep09: windows limits select() to 64 sockets by default, we increase it to 1024 here (before including winsock2.h)
85
+ #define FD_SETSIZE 1024
86
+
87
+ #define WIN32_LEAN_AND_MEAN
88
+ #include <windows.h>
89
+ #include <winsock2.h>
90
+ #include <ws2tcpip.h>
91
+ #include <rpc.h>
92
+ #include <fcntl.h>
93
+ #include <assert.h>
94
+
95
+ typedef int socklen_t;
96
+ typedef int pid_t;
97
+ #endif
98
+
99
+ #if !defined(_MSC_VER) || _MSC_VER > 1500
100
+ #include <stdint.h>
101
+ #endif
102
+
103
+ using namespace std;
104
+
105
+ #ifdef WITH_SSL
106
+ #include <openssl/ssl.h>
107
+ #include <openssl/err.h>
108
+ #endif
109
+
110
+ #ifdef HAVE_EPOLL
111
+ #include <sys/epoll.h>
112
+ #endif
113
+
114
+ #ifdef HAVE_KQUEUE
115
+ #include <sys/event.h>
116
+ #include <sys/queue.h>
117
+ #endif
118
+
119
+ #ifdef HAVE_INOTIFY
120
+ #include <sys/inotify.h>
121
+ #endif
122
+
123
+ #ifdef HAVE_OLD_INOTIFY
124
+ #include <sys/syscall.h>
125
+ #include <linux/inotify.h>
126
+ static inline int inotify_init (void) { return syscall (__NR_inotify_init); }
127
+ static inline int inotify_add_watch (int fd, const char *name, __u32 mask) { return syscall (__NR_inotify_add_watch, fd, name, mask); }
128
+ static inline int inotify_rm_watch (int fd, __u32 wd) { return syscall (__NR_inotify_rm_watch, fd, wd); }
129
+ #define HAVE_INOTIFY 1
130
+ #endif
131
+
132
+ #ifdef HAVE_INOTIFY
133
+ #define INOTIFY_EVENT_SIZE (sizeof(struct inotify_event))
134
+ #endif
135
+
136
+ #ifdef HAVE_WRITEV
137
+ #include <sys/uio.h>
138
+ #endif
139
+
140
+ #if __cplusplus
141
+ extern "C" {
142
+ #endif
143
+ typedef void (*EMCallback)(const unsigned long, int, const char*, const unsigned long);
144
+ #if __cplusplus
145
+ }
146
+ #endif
147
+
148
+ #include "binder.h"
149
+ #include "em.h"
150
+ #include "ed.h"
151
+ #include "page.h"
152
+ #include "ssl.h"
153
+ #include "eventmachine.h"
154
+
155
+ #endif // __Project__H_
data/ext/rubymain.cpp ADDED
@@ -0,0 +1,1269 @@
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
+ #ifndef RFLOAT_VALUE
25
+ #define RFLOAT_VALUE(arg) RFLOAT(arg)->value
26
+ #endif
27
+
28
+ /*******
29
+ Statics
30
+ *******/
31
+
32
+ static VALUE EmModule;
33
+ static VALUE EmConnection;
34
+ static VALUE EmConnsHash;
35
+ static VALUE EmTimersHash;
36
+
37
+ static VALUE EM_eConnectionError;
38
+ static VALUE EM_eUnknownTimerFired;
39
+ static VALUE EM_eConnectionNotBound;
40
+ static VALUE EM_eUnsupported;
41
+
42
+ static VALUE Intern_at_signature;
43
+ static VALUE Intern_at_timers;
44
+ static VALUE Intern_at_conns;
45
+ static VALUE Intern_at_error_handler;
46
+ static VALUE Intern_event_callback;
47
+ static VALUE Intern_run_deferred_callbacks;
48
+ static VALUE Intern_delete;
49
+ static VALUE Intern_call;
50
+ static VALUE Intern_receive_data;
51
+ static VALUE Intern_receive_error;
52
+ static VALUE Intern_ssl_handshake_completed;
53
+ static VALUE Intern_ssl_verify_peer;
54
+ static VALUE Intern_notify_readable;
55
+ static VALUE Intern_notify_writable;
56
+ static VALUE Intern_proxy_target_unbound;
57
+ static VALUE Intern_proxy_completed;
58
+ static VALUE Intern_connection_completed;
59
+
60
+ static VALUE rb_cProcStatus;
61
+
62
+ struct em_event {
63
+ unsigned long signature;
64
+ int event;
65
+ const char *data_str;
66
+ unsigned long data_num;
67
+ };
68
+
69
+ static inline VALUE ensure_conn(const unsigned long signature)
70
+ {
71
+ VALUE conn = rb_hash_aref (EmConnsHash, ULONG2NUM (signature));
72
+ if (conn == Qnil)
73
+ rb_raise (EM_eConnectionNotBound, "unknown connection: %lu", signature);
74
+ return conn;
75
+ }
76
+
77
+
78
+ /****************
79
+ t_event_callback
80
+ ****************/
81
+
82
+ static inline void event_callback (struct em_event* e)
83
+ {
84
+ const unsigned long signature = e->signature;
85
+ int event = e->event;
86
+ const char *data_str = e->data_str;
87
+ const unsigned long data_num = e->data_num;
88
+
89
+ switch (event) {
90
+ case EM_CONNECTION_READ:
91
+ {
92
+ VALUE conn = rb_hash_aref (EmConnsHash, ULONG2NUM (signature));
93
+ if (conn == Qnil)
94
+ rb_raise (EM_eConnectionNotBound, "received %lu bytes of data for unknown signature: %lu", data_num, signature);
95
+ rb_funcall (conn, Intern_receive_data, 1, rb_str_new (data_str, data_num));
96
+ return;
97
+ }
98
+ case EM_CONNECTION_SENDERROR:
99
+ {
100
+ VALUE conn = rb_hash_aref (EmConnsHash, ULONG2NUM (signature));
101
+ if (conn == Qnil)
102
+ rb_raise (EM_eConnectionNotBound, "received %lu bytes of data for unknown signature: %lu", data_num, signature);
103
+ rb_funcall (conn, Intern_receive_error, 1, rb_str_new (data_str, data_num));
104
+ return;
105
+ }
106
+ case EM_CONNECTION_ACCEPTED:
107
+ {
108
+ rb_funcall (EmModule, Intern_event_callback, 3, ULONG2NUM(signature), INT2FIX(event), ULONG2NUM(data_num));
109
+ return;
110
+ }
111
+ case EM_CONNECTION_UNBOUND:
112
+ {
113
+ rb_funcall (EmModule, Intern_event_callback, 3, ULONG2NUM(signature), INT2FIX(event), ULONG2NUM(data_num));
114
+ return;
115
+ }
116
+ case EM_CONNECTION_COMPLETED:
117
+ {
118
+ VALUE conn = ensure_conn(signature);
119
+ rb_funcall (conn, Intern_connection_completed, 0);
120
+ return;
121
+ }
122
+ case EM_CONNECTION_NOTIFY_READABLE:
123
+ {
124
+ VALUE conn = ensure_conn(signature);
125
+ rb_funcall (conn, Intern_notify_readable, 0);
126
+ return;
127
+ }
128
+ case EM_CONNECTION_NOTIFY_WRITABLE:
129
+ {
130
+ VALUE conn = ensure_conn(signature);
131
+ rb_funcall (conn, Intern_notify_writable, 0);
132
+ return;
133
+ }
134
+ case EM_LOOPBREAK_SIGNAL:
135
+ {
136
+ rb_funcall (EmModule, Intern_run_deferred_callbacks, 0);
137
+ return;
138
+ }
139
+ case EM_TIMER_FIRED:
140
+ {
141
+ VALUE timer = rb_funcall (EmTimersHash, Intern_delete, 1, ULONG2NUM (data_num));
142
+ if (timer == Qnil) {
143
+ rb_raise (EM_eUnknownTimerFired, "no such timer: %lu", data_num);
144
+ } else if (timer == Qfalse) {
145
+ /* Timer Canceled */
146
+ } else {
147
+ rb_funcall (timer, Intern_call, 0);
148
+ }
149
+ return;
150
+ }
151
+ #ifdef WITH_SSL
152
+ case EM_SSL_HANDSHAKE_COMPLETED:
153
+ {
154
+ VALUE conn = ensure_conn(signature);
155
+ rb_funcall (conn, Intern_ssl_handshake_completed, 0);
156
+ return;
157
+ }
158
+ case EM_SSL_VERIFY:
159
+ {
160
+ VALUE conn = ensure_conn(signature);
161
+ VALUE should_accept = rb_funcall (conn, Intern_ssl_verify_peer, 1, rb_str_new(data_str, data_num));
162
+ if (RTEST(should_accept))
163
+ evma_accept_ssl_peer (signature);
164
+ return;
165
+ }
166
+ #endif
167
+ case EM_PROXY_TARGET_UNBOUND:
168
+ {
169
+ VALUE conn = ensure_conn(signature);
170
+ rb_funcall (conn, Intern_proxy_target_unbound, 0);
171
+ return;
172
+ }
173
+ case EM_PROXY_COMPLETED:
174
+ {
175
+ VALUE conn = ensure_conn(signature);
176
+ rb_funcall (conn, Intern_proxy_completed, 0);
177
+ return;
178
+ }
179
+ }
180
+ }
181
+
182
+ /*******************
183
+ event_error_handler
184
+ *******************/
185
+
186
+ static void event_error_handler(VALUE unused, VALUE err)
187
+ {
188
+ VALUE error_handler = rb_ivar_get(EmModule, Intern_at_error_handler);
189
+ rb_funcall (error_handler, Intern_call, 1, err);
190
+ }
191
+
192
+ /**********************
193
+ event_callback_wrapper
194
+ **********************/
195
+
196
+ static void event_callback_wrapper (const unsigned long signature, int event, const char *data_str, const unsigned long data_num)
197
+ {
198
+ struct em_event e;
199
+ e.signature = signature;
200
+ e.event = event;
201
+ e.data_str = data_str;
202
+ e.data_num = data_num;
203
+
204
+ if (!rb_ivar_defined(EmModule, Intern_at_error_handler))
205
+ event_callback(&e);
206
+ else
207
+ rb_rescue((VALUE (*)(ANYARGS))event_callback, (VALUE)&e, (VALUE (*)(ANYARGS))event_error_handler, Qnil);
208
+ }
209
+
210
+ /**************************
211
+ t_initialize_event_machine
212
+ **************************/
213
+
214
+ static VALUE t_initialize_event_machine (VALUE self)
215
+ {
216
+ EmConnsHash = rb_ivar_get (EmModule, Intern_at_conns);
217
+ EmTimersHash = rb_ivar_get (EmModule, Intern_at_timers);
218
+ assert(EmConnsHash != Qnil);
219
+ assert(EmTimersHash != Qnil);
220
+ evma_initialize_library ((EMCallback)event_callback_wrapper);
221
+ return Qnil;
222
+ }
223
+
224
+
225
+
226
+ /*****************************
227
+ t_run_machine_without_threads
228
+ *****************************/
229
+
230
+ static VALUE t_run_machine_without_threads (VALUE self)
231
+ {
232
+ evma_run_machine();
233
+ return Qnil;
234
+ }
235
+
236
+
237
+ /*******************
238
+ t_add_oneshot_timer
239
+ *******************/
240
+
241
+ static VALUE t_add_oneshot_timer (VALUE self, VALUE interval)
242
+ {
243
+ const unsigned long f = evma_install_oneshot_timer (FIX2INT (interval));
244
+ return ULONG2NUM (f);
245
+ }
246
+
247
+
248
+ /**************
249
+ t_start_server
250
+ **************/
251
+
252
+ static VALUE t_start_server (VALUE self, VALUE server, VALUE port)
253
+ {
254
+ const unsigned long f = evma_create_tcp_server (StringValuePtr(server), FIX2INT(port));
255
+ if (!f)
256
+ rb_raise (rb_eRuntimeError, "no acceptor (port is in use or requires root privileges)");
257
+ return ULONG2NUM (f);
258
+ }
259
+
260
+ /*************
261
+ t_stop_server
262
+ *************/
263
+
264
+ static VALUE t_stop_server (VALUE self, VALUE signature)
265
+ {
266
+ evma_stop_tcp_server (NUM2ULONG (signature));
267
+ return Qnil;
268
+ }
269
+
270
+
271
+ /*******************
272
+ t_start_unix_server
273
+ *******************/
274
+
275
+ static VALUE t_start_unix_server (VALUE self, VALUE filename)
276
+ {
277
+ const unsigned long f = evma_create_unix_domain_server (StringValuePtr(filename));
278
+ if (!f)
279
+ rb_raise (rb_eRuntimeError, "no unix-domain acceptor");
280
+ return ULONG2NUM (f);
281
+ }
282
+
283
+
284
+
285
+ /***********
286
+ t_send_data
287
+ ***********/
288
+
289
+ static VALUE t_send_data (VALUE self, VALUE signature, VALUE data, VALUE data_length)
290
+ {
291
+ int b = evma_send_data_to_connection (NUM2ULONG (signature), StringValuePtr (data), FIX2INT (data_length));
292
+ return INT2NUM (b);
293
+ }
294
+
295
+
296
+ /***********
297
+ t_start_tls
298
+ ***********/
299
+
300
+ static VALUE t_start_tls (VALUE self, VALUE signature)
301
+ {
302
+ evma_start_tls (NUM2ULONG (signature));
303
+ return Qnil;
304
+ }
305
+
306
+ /***************
307
+ t_set_tls_parms
308
+ ***************/
309
+
310
+ static VALUE t_set_tls_parms (VALUE self, VALUE signature, VALUE privkeyfile, VALUE certchainfile, VALUE verify_peer)
311
+ {
312
+ /* set_tls_parms takes a series of positional arguments for specifying such things
313
+ * as private keys and certificate chains.
314
+ * It's expected that the parameter list will grow as we add more supported features.
315
+ * ALL of these parameters are optional, and can be specified as empty or NULL strings.
316
+ */
317
+ evma_set_tls_parms (NUM2ULONG (signature), StringValuePtr (privkeyfile), StringValuePtr (certchainfile), (verify_peer == Qtrue ? 1 : 0));
318
+ return Qnil;
319
+ }
320
+
321
+ /***************
322
+ t_get_peer_cert
323
+ ***************/
324
+
325
+ static VALUE t_get_peer_cert (VALUE self, VALUE signature)
326
+ {
327
+ VALUE ret = Qnil;
328
+
329
+ #ifdef WITH_SSL
330
+ X509 *cert = NULL;
331
+ BUF_MEM *buf;
332
+ BIO *out;
333
+
334
+ cert = evma_get_peer_cert (NUM2ULONG (signature));
335
+
336
+ if (cert != NULL) {
337
+ out = BIO_new(BIO_s_mem());
338
+ PEM_write_bio_X509(out, cert);
339
+ BIO_get_mem_ptr(out, &buf);
340
+ ret = rb_str_new(buf->data, buf->length);
341
+ X509_free(cert);
342
+ BUF_MEM_free(buf);
343
+ }
344
+ #endif
345
+
346
+ return ret;
347
+ }
348
+
349
+ /**************
350
+ t_get_peername
351
+ **************/
352
+
353
+ static VALUE t_get_peername (VALUE self, VALUE signature)
354
+ {
355
+ char buf[1024];
356
+ socklen_t len = sizeof buf;
357
+ if (evma_get_peername (NUM2ULONG (signature), (struct sockaddr_storage*)buf, &len)) {
358
+ return rb_str_new (buf, len);
359
+ }
360
+
361
+ return Qnil;
362
+ }
363
+
364
+ /**************
365
+ t_get_sockname
366
+ **************/
367
+
368
+ static VALUE t_get_sockname (VALUE self, VALUE signature)
369
+ {
370
+ char buf[1024];
371
+ socklen_t len = sizeof buf;
372
+ if (evma_get_sockname (NUM2ULONG (signature), (struct sockaddr_storage*)buf, &len)) {
373
+ return rb_str_new (buf, len);
374
+ }
375
+
376
+ return Qnil;
377
+ }
378
+
379
+ /********************
380
+ t_get_subprocess_pid
381
+ ********************/
382
+
383
+ static VALUE t_get_subprocess_pid (VALUE self, VALUE signature)
384
+ {
385
+ pid_t pid;
386
+ if (evma_get_subprocess_pid (NUM2ULONG (signature), &pid)) {
387
+ return INT2NUM (pid);
388
+ }
389
+
390
+ return Qnil;
391
+ }
392
+
393
+ /***********************
394
+ t_get_subprocess_status
395
+ ***********************/
396
+
397
+ static VALUE t_get_subprocess_status (VALUE self, VALUE signature)
398
+ {
399
+ VALUE proc_status = Qnil;
400
+
401
+ int status;
402
+ pid_t pid;
403
+
404
+ if (evma_get_subprocess_status (NUM2ULONG (signature), &status)) {
405
+ if (evma_get_subprocess_pid (NUM2ULONG (signature), &pid)) {
406
+ proc_status = rb_obj_alloc(rb_cProcStatus);
407
+ rb_iv_set(proc_status, "status", INT2FIX(status));
408
+ rb_iv_set(proc_status, "pid", INT2FIX(pid));
409
+ }
410
+ }
411
+
412
+ return proc_status;
413
+ }
414
+
415
+ /**********************
416
+ t_get_connection_count
417
+ **********************/
418
+
419
+ static VALUE t_get_connection_count (VALUE self)
420
+ {
421
+ return INT2NUM(evma_get_connection_count());
422
+ }
423
+
424
+ /*****************************
425
+ t_get_comm_inactivity_timeout
426
+ *****************************/
427
+
428
+ static VALUE t_get_comm_inactivity_timeout (VALUE self, VALUE signature)
429
+ {
430
+ return rb_float_new(evma_get_comm_inactivity_timeout(NUM2ULONG (signature)));
431
+ }
432
+
433
+ /*****************************
434
+ t_set_comm_inactivity_timeout
435
+ *****************************/
436
+
437
+ static VALUE t_set_comm_inactivity_timeout (VALUE self, VALUE signature, VALUE timeout)
438
+ {
439
+ float ti = RFLOAT_VALUE(timeout);
440
+ if (evma_set_comm_inactivity_timeout(NUM2ULONG(signature), ti)) {
441
+ return Qtrue;
442
+ }
443
+ return Qfalse;
444
+ }
445
+
446
+ /*****************************
447
+ t_get_pending_connect_timeout
448
+ *****************************/
449
+
450
+ static VALUE t_get_pending_connect_timeout (VALUE self, VALUE signature)
451
+ {
452
+ return rb_float_new(evma_get_pending_connect_timeout(NUM2ULONG (signature)));
453
+ }
454
+
455
+ /*****************************
456
+ t_set_pending_connect_timeout
457
+ *****************************/
458
+
459
+ static VALUE t_set_pending_connect_timeout (VALUE self, VALUE signature, VALUE timeout)
460
+ {
461
+ float ti = RFLOAT_VALUE(timeout);
462
+ if (evma_set_pending_connect_timeout(NUM2ULONG(signature), ti)) {
463
+ return Qtrue;
464
+ }
465
+ return Qfalse;
466
+ }
467
+
468
+ /***************
469
+ t_send_datagram
470
+ ***************/
471
+
472
+ static VALUE t_send_datagram (VALUE self, VALUE signature, VALUE data, VALUE data_length, VALUE address, VALUE port)
473
+ {
474
+ int b = evma_send_datagram (NUM2ULONG (signature), StringValuePtr (data), FIX2INT (data_length), StringValuePtr(address), FIX2INT(port));
475
+ if (b < 0)
476
+ rb_raise (EM_eConnectionError, "error in sending datagram"); // FIXME: this could be more specific.
477
+ return INT2NUM (b);
478
+ }
479
+
480
+
481
+ /******************
482
+ t_close_connection
483
+ ******************/
484
+
485
+ static VALUE t_close_connection (VALUE self, VALUE signature, VALUE after_writing)
486
+ {
487
+ evma_close_connection (NUM2ULONG (signature), ((after_writing == Qtrue) ? 1 : 0));
488
+ return Qnil;
489
+ }
490
+
491
+ /********************************
492
+ t_report_connection_error_status
493
+ ********************************/
494
+
495
+ static VALUE t_report_connection_error_status (VALUE self, VALUE signature)
496
+ {
497
+ int b = evma_report_connection_error_status (NUM2ULONG (signature));
498
+ return INT2NUM (b);
499
+ }
500
+
501
+
502
+
503
+ /****************
504
+ t_connect_server
505
+ ****************/
506
+
507
+ static VALUE t_connect_server (VALUE self, VALUE server, VALUE port)
508
+ {
509
+ // Avoid FIX2INT in this case, because it doesn't deal with type errors properly.
510
+ // Specifically, if the value of port comes in as a string rather than an integer,
511
+ // NUM2INT will throw a type error, but FIX2INT will generate garbage.
512
+
513
+ try {
514
+ const unsigned long f = evma_connect_to_server (NULL, 0, StringValuePtr(server), NUM2INT(port));
515
+ if (!f)
516
+ rb_raise (EM_eConnectionError, "no connection");
517
+ return ULONG2NUM (f);
518
+ } catch (std::runtime_error e) {
519
+ rb_raise (EM_eConnectionError, e.what());
520
+ }
521
+ return Qnil;
522
+ }
523
+
524
+ /*********************
525
+ t_bind_connect_server
526
+ *********************/
527
+
528
+ static VALUE t_bind_connect_server (VALUE self, VALUE bind_addr, VALUE bind_port, VALUE server, VALUE port)
529
+ {
530
+ // Avoid FIX2INT in this case, because it doesn't deal with type errors properly.
531
+ // Specifically, if the value of port comes in as a string rather than an integer,
532
+ // NUM2INT will throw a type error, but FIX2INT will generate garbage.
533
+
534
+ try {
535
+ const unsigned long f = evma_connect_to_server (StringValuePtr(bind_addr), NUM2INT(bind_port), StringValuePtr(server), NUM2INT(port));
536
+ if (!f)
537
+ rb_raise (EM_eConnectionError, "no connection");
538
+ return ULONG2NUM (f);
539
+ } catch (std::runtime_error e) {
540
+ rb_raise (EM_eConnectionError, e.what());
541
+ }
542
+ return Qnil;
543
+ }
544
+
545
+ /*********************
546
+ t_connect_unix_server
547
+ *********************/
548
+
549
+ static VALUE t_connect_unix_server (VALUE self, VALUE serversocket)
550
+ {
551
+ const unsigned long f = evma_connect_to_unix_server (StringValuePtr(serversocket));
552
+ if (!f)
553
+ rb_raise (rb_eRuntimeError, "no connection");
554
+ return ULONG2NUM (f);
555
+ }
556
+
557
+ /***********
558
+ t_attach_fd
559
+ ***********/
560
+
561
+ static VALUE t_attach_fd (VALUE self, VALUE file_descriptor, VALUE watch_mode)
562
+ {
563
+ const unsigned long f = evma_attach_fd (NUM2INT(file_descriptor), watch_mode == Qtrue);
564
+ if (!f)
565
+ rb_raise (rb_eRuntimeError, "no connection");
566
+ return ULONG2NUM (f);
567
+ }
568
+
569
+ /***********
570
+ t_detach_fd
571
+ ***********/
572
+
573
+ static VALUE t_detach_fd (VALUE self, VALUE signature)
574
+ {
575
+ return INT2NUM(evma_detach_fd (NUM2ULONG (signature)));
576
+ }
577
+
578
+ /***********
579
+ t_attach_server_fd
580
+ ***********/
581
+
582
+ static VALUE t_attach_server_fd (VALUE self, VALUE file_descriptor, VALUE watch_mode)
583
+ {
584
+ const unsigned long f = evma_attach_server_fd (NUM2INT(file_descriptor));
585
+ if (!f)
586
+ rb_raise (rb_eRuntimeError, "no connection");
587
+ return ULONG2NUM (f);
588
+ }
589
+
590
+ /**************
591
+ t_get_sock_opt
592
+ **************/
593
+
594
+ static VALUE t_get_sock_opt (VALUE self, VALUE signature, VALUE lev, VALUE optname)
595
+ {
596
+ int fd = evma_get_file_descriptor (NUM2ULONG (signature));
597
+ int level = NUM2INT(lev), option = NUM2INT(optname);
598
+ socklen_t len = 128;
599
+ char buf[128];
600
+
601
+ if (getsockopt(fd, level, option, buf, &len) < 0)
602
+ rb_sys_fail("getsockopt");
603
+
604
+ return rb_str_new(buf, len);
605
+ }
606
+
607
+ /**************
608
+ t_set_sock_opt
609
+ **************/
610
+
611
+ static VALUE t_set_sock_opt (VALUE self, VALUE signature, VALUE lev, VALUE optname, VALUE optval)
612
+ {
613
+ int fd = evma_get_file_descriptor (NUM2ULONG (signature));
614
+ int level = NUM2INT(lev), option = NUM2INT(optname);
615
+ int i;
616
+ void *v;
617
+ socklen_t len;
618
+
619
+ switch (TYPE(optval)) {
620
+ case T_FIXNUM:
621
+ i = FIX2INT(optval);
622
+ goto numval;
623
+ case T_FALSE:
624
+ i = 0;
625
+ goto numval;
626
+ case T_TRUE:
627
+ i = 1;
628
+ numval:
629
+ v = (void*)&i; len = sizeof(i);
630
+ break;
631
+ default:
632
+ StringValue(optval);
633
+ v = RSTRING_PTR(optval);
634
+ len = RSTRING_LENINT(optval);
635
+ break;
636
+ }
637
+
638
+
639
+ if (setsockopt(fd, level, option, (char *)v, len) < 0)
640
+ rb_sys_fail("setsockopt");
641
+
642
+ return INT2FIX(0);
643
+ }
644
+
645
+ /********************
646
+ t_is_notify_readable
647
+ ********************/
648
+
649
+ static VALUE t_is_notify_readable (VALUE self, VALUE signature)
650
+ {
651
+ return evma_is_notify_readable(NUM2ULONG (signature)) ? Qtrue : Qfalse;
652
+ }
653
+
654
+ /*********************
655
+ t_set_notify_readable
656
+ *********************/
657
+
658
+ static VALUE t_set_notify_readable (VALUE self, VALUE signature, VALUE mode)
659
+ {
660
+ evma_set_notify_readable(NUM2ULONG (signature), mode == Qtrue);
661
+ return Qnil;
662
+ }
663
+
664
+ /********************
665
+ t_is_notify_readable
666
+ ********************/
667
+
668
+ static VALUE t_is_notify_writable (VALUE self, VALUE signature)
669
+ {
670
+ return evma_is_notify_writable(NUM2ULONG (signature)) ? Qtrue : Qfalse;
671
+ }
672
+
673
+ /*********************
674
+ t_set_notify_writable
675
+ *********************/
676
+
677
+ static VALUE t_set_notify_writable (VALUE self, VALUE signature, VALUE mode)
678
+ {
679
+ evma_set_notify_writable(NUM2ULONG (signature), mode == Qtrue);
680
+ return Qnil;
681
+ }
682
+
683
+ /*********************
684
+ t_set_error_handling
685
+ *********************/
686
+
687
+ static VALUE t_set_error_handling (VALUE self, VALUE signature, VALUE mode)
688
+ {
689
+ evma_set_error_handling(NUM2ULONG (signature), NUM2INT(mode));
690
+ return Qnil;
691
+ }
692
+
693
+ /*******
694
+ t_pause
695
+ *******/
696
+
697
+ static VALUE t_pause (VALUE self, VALUE signature)
698
+ {
699
+ return evma_pause(NUM2ULONG (signature)) ? Qtrue : Qfalse;
700
+ }
701
+
702
+ /********
703
+ t_resume
704
+ ********/
705
+
706
+ static VALUE t_resume (VALUE self, VALUE signature)
707
+ {
708
+ return evma_resume(NUM2ULONG (signature)) ? Qtrue : Qfalse;
709
+ }
710
+
711
+ /**********
712
+ t_paused_p
713
+ **********/
714
+
715
+ static VALUE t_paused_p (VALUE self, VALUE signature)
716
+ {
717
+ return evma_is_paused(NUM2ULONG (signature)) ? Qtrue : Qfalse;
718
+ }
719
+
720
+ /*********************
721
+ t_num_close_scheduled
722
+ *********************/
723
+
724
+ static VALUE t_num_close_scheduled (VALUE self)
725
+ {
726
+ return INT2FIX(evma_num_close_scheduled());
727
+ }
728
+
729
+ /*****************
730
+ t_open_udp_socket
731
+ *****************/
732
+
733
+ static VALUE t_open_udp_socket (VALUE self, VALUE server, VALUE port)
734
+ {
735
+ const unsigned long f = evma_open_datagram_socket (StringValuePtr(server), FIX2INT(port));
736
+ if (!f)
737
+ rb_raise (rb_eRuntimeError, "no datagram socket");
738
+ return ULONG2NUM (f);
739
+ }
740
+
741
+
742
+
743
+ /*****************
744
+ t_release_machine
745
+ *****************/
746
+
747
+ static VALUE t_release_machine (VALUE self)
748
+ {
749
+ evma_release_library();
750
+ return Qnil;
751
+ }
752
+
753
+
754
+ /******
755
+ t_stop
756
+ ******/
757
+
758
+ static VALUE t_stop (VALUE self)
759
+ {
760
+ evma_stop_machine();
761
+ return Qnil;
762
+ }
763
+
764
+ /******************
765
+ t_signal_loopbreak
766
+ ******************/
767
+
768
+ static VALUE t_signal_loopbreak (VALUE self)
769
+ {
770
+ evma_signal_loopbreak();
771
+ return Qnil;
772
+ }
773
+
774
+ /**************
775
+ t_library_type
776
+ **************/
777
+
778
+ static VALUE t_library_type (VALUE self)
779
+ {
780
+ return rb_eval_string (":extension");
781
+ }
782
+
783
+
784
+ /*******************
785
+ t_set_timer_quantum
786
+ *******************/
787
+
788
+ static VALUE t_set_timer_quantum (VALUE self, VALUE interval)
789
+ {
790
+ evma_set_timer_quantum (FIX2INT (interval));
791
+ return Qnil;
792
+ }
793
+
794
+
795
+ /***************
796
+ t_setuid_string
797
+ ***************/
798
+
799
+ static VALUE t_setuid_string (VALUE self, VALUE username)
800
+ {
801
+ evma_setuid_string (StringValuePtr (username));
802
+ return Qnil;
803
+ }
804
+
805
+
806
+ /**************
807
+ t_invoke_popen
808
+ **************/
809
+
810
+ static VALUE t_invoke_popen (VALUE self, VALUE cmd)
811
+ {
812
+ // 1.8.7+
813
+ #ifdef RARRAY_LEN
814
+ int len = RARRAY_LEN(cmd);
815
+ #else
816
+ int len = RARRAY (cmd)->len;
817
+ #endif
818
+ if (len >= 2048)
819
+ rb_raise (rb_eRuntimeError, "too many arguments to popen");
820
+ char *strings [2048];
821
+ for (int i=0; i < len; i++) {
822
+ VALUE ix = INT2FIX (i);
823
+ VALUE s = rb_ary_aref (1, &ix, cmd);
824
+ strings[i] = StringValuePtr (s);
825
+ }
826
+ strings[len] = NULL;
827
+
828
+ const unsigned long f = evma_popen (strings);
829
+ if (!f) {
830
+ char *err = strerror (errno);
831
+ char buf[100];
832
+ memset (buf, 0, sizeof(buf));
833
+ snprintf (buf, sizeof(buf)-1, "no popen: %s", (err?err:"???"));
834
+ rb_raise (rb_eRuntimeError, "%s", buf);
835
+ }
836
+ return ULONG2NUM (f);
837
+ }
838
+
839
+
840
+ /***************
841
+ t_read_keyboard
842
+ ***************/
843
+
844
+ static VALUE t_read_keyboard (VALUE self)
845
+ {
846
+ const unsigned long f = evma_open_keyboard();
847
+ if (!f)
848
+ rb_raise (rb_eRuntimeError, "no keyboard reader");
849
+ return ULONG2NUM (f);
850
+ }
851
+
852
+
853
+ /****************
854
+ t_watch_filename
855
+ ****************/
856
+
857
+ static VALUE t_watch_filename (VALUE self, VALUE fname)
858
+ {
859
+ try {
860
+ return ULONG2NUM(evma_watch_filename(StringValuePtr(fname)));
861
+ } catch (std::runtime_error e) {
862
+ rb_raise (EM_eUnsupported, e.what());
863
+ }
864
+ return Qnil;
865
+ }
866
+
867
+
868
+ /******************
869
+ t_unwatch_filename
870
+ ******************/
871
+
872
+ static VALUE t_unwatch_filename (VALUE self, VALUE sig)
873
+ {
874
+ evma_unwatch_filename(NUM2ULONG (sig));
875
+ return Qnil;
876
+ }
877
+
878
+
879
+ /***********
880
+ t_watch_pid
881
+ ***********/
882
+
883
+ static VALUE t_watch_pid (VALUE self, VALUE pid)
884
+ {
885
+ try {
886
+ return ULONG2NUM(evma_watch_pid(NUM2INT(pid)));
887
+ } catch (std::runtime_error e) {
888
+ rb_raise (EM_eUnsupported, e.what());
889
+ }
890
+ return Qnil;
891
+ }
892
+
893
+
894
+ /*************
895
+ t_unwatch_pid
896
+ *************/
897
+
898
+ static VALUE t_unwatch_pid (VALUE self, VALUE sig)
899
+ {
900
+ evma_unwatch_pid(NUM2ULONG (sig));
901
+ return Qnil;
902
+ }
903
+
904
+
905
+ /**********
906
+ t__epoll_p
907
+ **********/
908
+
909
+ static VALUE t__epoll_p (VALUE self)
910
+ {
911
+ #ifdef HAVE_EPOLL
912
+ return Qtrue;
913
+ #else
914
+ return Qfalse;
915
+ #endif
916
+ }
917
+
918
+ /********
919
+ t__epoll
920
+ ********/
921
+
922
+ static VALUE t__epoll (VALUE self)
923
+ {
924
+ evma_set_epoll (1);
925
+ return Qtrue;
926
+ }
927
+
928
+ /***********
929
+ t__epoll_set
930
+ ***********/
931
+
932
+ static VALUE t__epoll_set (VALUE self, VALUE val)
933
+ {
934
+ if (t__epoll_p(self) == Qfalse)
935
+ rb_raise (EM_eUnsupported, "epoll is not supported on this platform");
936
+
937
+ evma_set_epoll (val == Qtrue ? 1 : 0);
938
+ return val;
939
+ }
940
+
941
+
942
+ /***********
943
+ t__kqueue_p
944
+ ***********/
945
+
946
+ static VALUE t__kqueue_p (VALUE self)
947
+ {
948
+ #ifdef HAVE_KQUEUE
949
+ return Qtrue;
950
+ #else
951
+ return Qfalse;
952
+ #endif
953
+ }
954
+
955
+ /*********
956
+ t__kqueue
957
+ *********/
958
+
959
+ static VALUE t__kqueue (VALUE self)
960
+ {
961
+ evma_set_kqueue (1);
962
+ return Qtrue;
963
+ }
964
+
965
+ /*************
966
+ t__kqueue_set
967
+ *************/
968
+
969
+ static VALUE t__kqueue_set (VALUE self, VALUE val)
970
+ {
971
+ if (t__kqueue_p(self) == Qfalse)
972
+ rb_raise (EM_eUnsupported, "kqueue is not supported on this platform");
973
+
974
+ evma_set_kqueue (val == Qtrue ? 1 : 0);
975
+ return val;
976
+ }
977
+
978
+
979
+ /********
980
+ t__ssl_p
981
+ ********/
982
+
983
+ static VALUE t__ssl_p (VALUE self)
984
+ {
985
+ #ifdef WITH_SSL
986
+ return Qtrue;
987
+ #else
988
+ return Qfalse;
989
+ #endif
990
+ }
991
+
992
+
993
+ /****************
994
+ t_send_file_data
995
+ ****************/
996
+
997
+ static VALUE t_send_file_data (VALUE self, VALUE signature, VALUE filename)
998
+ {
999
+
1000
+ /* The current implementation of evma_send_file_data_to_connection enforces a strict
1001
+ * upper limit on the file size it will transmit (currently 32K). The function returns
1002
+ * zero on success, -1 if the requested file exceeds its size limit, and a positive
1003
+ * number for other errors.
1004
+ * TODO: Positive return values are actually errno's, which is probably the wrong way to
1005
+ * do this. For one thing it's ugly. For another, we can't be sure zero is never a real errno.
1006
+ */
1007
+
1008
+ int b = evma_send_file_data_to_connection (NUM2ULONG (signature), StringValuePtr(filename));
1009
+ if (b == -1)
1010
+ rb_raise(rb_eRuntimeError, "File too large. send_file_data() supports files under 32k.");
1011
+ if (b > 0) {
1012
+ char *err = strerror (b);
1013
+ char buf[1024];
1014
+ memset (buf, 0, sizeof(buf));
1015
+ snprintf (buf, sizeof(buf)-1, ": %s %s", StringValuePtr(filename),(err?err:"???"));
1016
+
1017
+ rb_raise (rb_eIOError, "%s", buf);
1018
+ }
1019
+
1020
+ return INT2NUM (0);
1021
+ }
1022
+
1023
+
1024
+ /*******************
1025
+ t_set_rlimit_nofile
1026
+ *******************/
1027
+
1028
+ static VALUE t_set_rlimit_nofile (VALUE self, VALUE arg)
1029
+ {
1030
+ arg = (NIL_P(arg)) ? -1 : NUM2INT (arg);
1031
+ return INT2NUM (evma_set_rlimit_nofile (arg));
1032
+ }
1033
+
1034
+ /***************************
1035
+ conn_get_outbound_data_size
1036
+ ***************************/
1037
+
1038
+ static VALUE conn_get_outbound_data_size (VALUE self)
1039
+ {
1040
+ VALUE sig = rb_ivar_get (self, Intern_at_signature);
1041
+ return INT2NUM (evma_get_outbound_data_size (NUM2ULONG (sig)));
1042
+ }
1043
+
1044
+
1045
+ /******************************
1046
+ conn_associate_callback_target
1047
+ ******************************/
1048
+
1049
+ static VALUE conn_associate_callback_target (VALUE self, VALUE sig)
1050
+ {
1051
+ // No-op for the time being.
1052
+ return Qnil;
1053
+ }
1054
+
1055
+
1056
+ /***************
1057
+ t_get_loop_time
1058
+ ****************/
1059
+
1060
+ static VALUE t_get_loop_time (VALUE self)
1061
+ {
1062
+ #ifndef HAVE_RB_TIME_NEW
1063
+ static VALUE cTime = rb_path2class("Time");
1064
+ static ID at = rb_intern("at");
1065
+ #endif
1066
+
1067
+ uint64_t current_time = evma_get_current_loop_time();
1068
+ if (current_time != 0) {
1069
+ #ifndef HAVE_RB_TIME_NEW
1070
+ return rb_funcall(cTime, at, 2, INT2NUM(current_time / 1000000), INT2NUM(current_time % 1000000));
1071
+ #else
1072
+ return rb_time_new(current_time / 1000000, current_time % 1000000);
1073
+ #endif
1074
+ }
1075
+ return Qnil;
1076
+ }
1077
+
1078
+
1079
+ /*************
1080
+ t_start_proxy
1081
+ **************/
1082
+
1083
+ static VALUE t_start_proxy (VALUE self, VALUE from, VALUE to, VALUE bufsize, VALUE length)
1084
+ {
1085
+ try {
1086
+ evma_start_proxy(NUM2ULONG (from), NUM2ULONG (to), NUM2ULONG(bufsize), NUM2ULONG(length));
1087
+ } catch (std::runtime_error e) {
1088
+ rb_raise (EM_eConnectionError, e.what());
1089
+ }
1090
+ return Qnil;
1091
+ }
1092
+
1093
+
1094
+ /************
1095
+ t_stop_proxy
1096
+ *************/
1097
+
1098
+ static VALUE t_stop_proxy (VALUE self, VALUE from)
1099
+ {
1100
+ try{
1101
+ evma_stop_proxy(NUM2ULONG (from));
1102
+ } catch (std::runtime_error e) {
1103
+ rb_raise (EM_eConnectionError, e.what());
1104
+ }
1105
+ return Qnil;
1106
+ }
1107
+
1108
+
1109
+ /************************
1110
+ t_get_heartbeat_interval
1111
+ *************************/
1112
+
1113
+ static VALUE t_get_heartbeat_interval (VALUE self)
1114
+ {
1115
+ return rb_float_new(evma_get_heartbeat_interval());
1116
+ }
1117
+
1118
+
1119
+ /************************
1120
+ t_set_heartbeat_interval
1121
+ *************************/
1122
+
1123
+ static VALUE t_set_heartbeat_interval (VALUE self, VALUE interval)
1124
+ {
1125
+ float iv = RFLOAT_VALUE(interval);
1126
+ if (evma_set_heartbeat_interval(iv))
1127
+ return Qtrue;
1128
+ return Qfalse;
1129
+ }
1130
+
1131
+
1132
+ /*********************
1133
+ Init_rubyeventmachine
1134
+ *********************/
1135
+
1136
+ extern "C" void Init_rubyeventmachine()
1137
+ {
1138
+ // Lookup Process::Status for get_subprocess_status
1139
+ VALUE rb_mProcess = rb_const_get(rb_cObject, rb_intern("Process"));
1140
+ rb_cProcStatus = rb_const_get(rb_mProcess, rb_intern("Status"));
1141
+
1142
+ // Tuck away some symbol values so we don't have to look 'em up every time we need 'em.
1143
+ Intern_at_signature = rb_intern ("@signature");
1144
+ Intern_at_timers = rb_intern ("@timers");
1145
+ Intern_at_conns = rb_intern ("@conns");
1146
+ Intern_at_error_handler = rb_intern("@error_handler");
1147
+
1148
+ Intern_event_callback = rb_intern ("event_callback");
1149
+ Intern_run_deferred_callbacks = rb_intern ("run_deferred_callbacks");
1150
+ Intern_delete = rb_intern ("delete");
1151
+ Intern_call = rb_intern ("call");
1152
+ Intern_receive_data = rb_intern ("receive_data");
1153
+ Intern_receive_error = rb_intern ("receive_error");
1154
+ Intern_ssl_handshake_completed = rb_intern ("ssl_handshake_completed");
1155
+ Intern_ssl_verify_peer = rb_intern ("ssl_verify_peer");
1156
+ Intern_notify_readable = rb_intern ("notify_readable");
1157
+ Intern_notify_writable = rb_intern ("notify_writable");
1158
+ Intern_proxy_target_unbound = rb_intern ("proxy_target_unbound");
1159
+ Intern_proxy_completed = rb_intern ("proxy_completed");
1160
+ Intern_connection_completed = rb_intern ("connection_completed");
1161
+
1162
+ // INCOMPLETE, we need to define class Connections inside module EventMachine
1163
+ // run_machine and run_machine_without_threads are now identical.
1164
+ // Must deprecate the without_threads variant.
1165
+ EmModule = rb_define_module ("EventMachine");
1166
+ EmConnection = rb_define_class_under (EmModule, "Connection", rb_cObject);
1167
+
1168
+ rb_define_class_under (EmModule, "NoHandlerForAcceptedConnection", rb_eRuntimeError);
1169
+ EM_eConnectionError = rb_define_class_under (EmModule, "ConnectionError", rb_eRuntimeError);
1170
+ EM_eConnectionNotBound = rb_define_class_under (EmModule, "ConnectionNotBound", rb_eRuntimeError);
1171
+ EM_eUnknownTimerFired = rb_define_class_under (EmModule, "UnknownTimerFired", rb_eRuntimeError);
1172
+ EM_eUnsupported = rb_define_class_under (EmModule, "Unsupported", rb_eRuntimeError);
1173
+
1174
+ rb_define_module_function (EmModule, "initialize_event_machine", (VALUE(*)(...))t_initialize_event_machine, 0);
1175
+ rb_define_module_function (EmModule, "run_machine", (VALUE(*)(...))t_run_machine_without_threads, 0);
1176
+ rb_define_module_function (EmModule, "run_machine_without_threads", (VALUE(*)(...))t_run_machine_without_threads, 0);
1177
+ rb_define_module_function (EmModule, "add_oneshot_timer", (VALUE(*)(...))t_add_oneshot_timer, 1);
1178
+ rb_define_module_function (EmModule, "start_tcp_server", (VALUE(*)(...))t_start_server, 2);
1179
+ rb_define_module_function (EmModule, "stop_tcp_server", (VALUE(*)(...))t_stop_server, 1);
1180
+ rb_define_module_function (EmModule, "start_unix_server", (VALUE(*)(...))t_start_unix_server, 1);
1181
+ rb_define_module_function (EmModule, "set_tls_parms", (VALUE(*)(...))t_set_tls_parms, 4);
1182
+ rb_define_module_function (EmModule, "start_tls", (VALUE(*)(...))t_start_tls, 1);
1183
+ rb_define_module_function (EmModule, "get_peer_cert", (VALUE(*)(...))t_get_peer_cert, 1);
1184
+ rb_define_module_function (EmModule, "send_data", (VALUE(*)(...))t_send_data, 3);
1185
+ rb_define_module_function (EmModule, "send_datagram", (VALUE(*)(...))t_send_datagram, 5);
1186
+ rb_define_module_function (EmModule, "close_connection", (VALUE(*)(...))t_close_connection, 2);
1187
+ rb_define_module_function (EmModule, "report_connection_error_status", (VALUE(*)(...))t_report_connection_error_status, 1);
1188
+ rb_define_module_function (EmModule, "connect_server", (VALUE(*)(...))t_connect_server, 2);
1189
+ rb_define_module_function (EmModule, "bind_connect_server", (VALUE(*)(...))t_bind_connect_server, 4);
1190
+ rb_define_module_function (EmModule, "connect_unix_server", (VALUE(*)(...))t_connect_unix_server, 1);
1191
+
1192
+ rb_define_module_function (EmModule, "attach_fd", (VALUE (*)(...))t_attach_fd, 2);
1193
+ rb_define_module_function (EmModule, "detach_fd", (VALUE (*)(...))t_detach_fd, 1);
1194
+ rb_define_module_function (EmModule, "attach_server_fd", (VALUE (*)(...))t_attach_server_fd, 1);
1195
+ rb_define_module_function (EmModule, "get_sock_opt", (VALUE (*)(...))t_get_sock_opt, 3);
1196
+ rb_define_module_function (EmModule, "set_sock_opt", (VALUE (*)(...))t_set_sock_opt, 4);
1197
+ rb_define_module_function (EmModule, "set_notify_readable", (VALUE (*)(...))t_set_notify_readable, 2);
1198
+ rb_define_module_function (EmModule, "set_notify_writable", (VALUE (*)(...))t_set_notify_writable, 2);
1199
+ rb_define_module_function (EmModule, "set_error_handling", (VALUE (*)(...))t_set_error_handling, 2);
1200
+ rb_define_module_function (EmModule, "is_notify_readable", (VALUE (*)(...))t_is_notify_readable, 1);
1201
+ rb_define_module_function (EmModule, "is_notify_writable", (VALUE (*)(...))t_is_notify_writable, 1);
1202
+
1203
+ rb_define_module_function (EmModule, "pause_connection", (VALUE (*)(...))t_pause, 1);
1204
+ rb_define_module_function (EmModule, "resume_connection", (VALUE (*)(...))t_resume, 1);
1205
+ rb_define_module_function (EmModule, "connection_paused?", (VALUE (*)(...))t_paused_p, 1);
1206
+ rb_define_module_function (EmModule, "num_close_scheduled", (VALUE (*)(...))t_num_close_scheduled, 0);
1207
+
1208
+ rb_define_module_function (EmModule, "start_proxy", (VALUE (*)(...))t_start_proxy, 4);
1209
+ rb_define_module_function (EmModule, "stop_proxy", (VALUE (*)(...))t_stop_proxy, 1);
1210
+
1211
+ rb_define_module_function (EmModule, "watch_filename", (VALUE (*)(...))t_watch_filename, 1);
1212
+ rb_define_module_function (EmModule, "unwatch_filename", (VALUE (*)(...))t_unwatch_filename, 1);
1213
+
1214
+ rb_define_module_function (EmModule, "watch_pid", (VALUE (*)(...))t_watch_pid, 1);
1215
+ rb_define_module_function (EmModule, "unwatch_pid", (VALUE (*)(...))t_unwatch_pid, 1);
1216
+
1217
+ rb_define_module_function (EmModule, "current_time", (VALUE(*)(...))t_get_loop_time, 0);
1218
+
1219
+ rb_define_module_function (EmModule, "open_udp_socket", (VALUE(*)(...))t_open_udp_socket, 2);
1220
+ rb_define_module_function (EmModule, "read_keyboard", (VALUE(*)(...))t_read_keyboard, 0);
1221
+ rb_define_module_function (EmModule, "release_machine", (VALUE(*)(...))t_release_machine, 0);
1222
+ rb_define_module_function (EmModule, "stop", (VALUE(*)(...))t_stop, 0);
1223
+ rb_define_module_function (EmModule, "signal_loopbreak", (VALUE(*)(...))t_signal_loopbreak, 0);
1224
+ rb_define_module_function (EmModule, "library_type", (VALUE(*)(...))t_library_type, 0);
1225
+ rb_define_module_function (EmModule, "set_timer_quantum", (VALUE(*)(...))t_set_timer_quantum, 1);
1226
+ rb_define_module_function (EmModule, "setuid_string", (VALUE(*)(...))t_setuid_string, 1);
1227
+ rb_define_module_function (EmModule, "invoke_popen", (VALUE(*)(...))t_invoke_popen, 1);
1228
+ rb_define_module_function (EmModule, "send_file_data", (VALUE(*)(...))t_send_file_data, 2);
1229
+ rb_define_module_function (EmModule, "get_heartbeat_interval", (VALUE(*)(...))t_get_heartbeat_interval, 0);
1230
+ rb_define_module_function (EmModule, "set_heartbeat_interval", (VALUE(*)(...))t_set_heartbeat_interval, 1);
1231
+
1232
+ rb_define_module_function (EmModule, "get_peername", (VALUE(*)(...))t_get_peername, 1);
1233
+ rb_define_module_function (EmModule, "get_sockname", (VALUE(*)(...))t_get_sockname, 1);
1234
+ rb_define_module_function (EmModule, "get_subprocess_pid", (VALUE(*)(...))t_get_subprocess_pid, 1);
1235
+ rb_define_module_function (EmModule, "get_subprocess_status", (VALUE(*)(...))t_get_subprocess_status, 1);
1236
+ rb_define_module_function (EmModule, "get_comm_inactivity_timeout", (VALUE(*)(...))t_get_comm_inactivity_timeout, 1);
1237
+ rb_define_module_function (EmModule, "set_comm_inactivity_timeout", (VALUE(*)(...))t_set_comm_inactivity_timeout, 2);
1238
+ rb_define_module_function (EmModule, "get_pending_connect_timeout", (VALUE(*)(...))t_get_pending_connect_timeout, 1);
1239
+ rb_define_module_function (EmModule, "set_pending_connect_timeout", (VALUE(*)(...))t_set_pending_connect_timeout, 2);
1240
+ rb_define_module_function (EmModule, "set_rlimit_nofile", (VALUE(*)(...))t_set_rlimit_nofile, 1);
1241
+ rb_define_module_function (EmModule, "get_connection_count", (VALUE(*)(...))t_get_connection_count, 0);
1242
+
1243
+ rb_define_module_function (EmModule, "epoll", (VALUE(*)(...))t__epoll, 0);
1244
+ rb_define_module_function (EmModule, "epoll=", (VALUE(*)(...))t__epoll_set, 1);
1245
+ rb_define_module_function (EmModule, "epoll?", (VALUE(*)(...))t__epoll_p, 0);
1246
+
1247
+ rb_define_module_function (EmModule, "kqueue", (VALUE(*)(...))t__kqueue, 0);
1248
+ rb_define_module_function (EmModule, "kqueue=", (VALUE(*)(...))t__kqueue_set, 1);
1249
+ rb_define_module_function (EmModule, "kqueue?", (VALUE(*)(...))t__kqueue_p, 0);
1250
+
1251
+ rb_define_module_function (EmModule, "ssl?", (VALUE(*)(...))t__ssl_p, 0);
1252
+
1253
+ rb_define_method (EmConnection, "get_outbound_data_size", (VALUE(*)(...))conn_get_outbound_data_size, 0);
1254
+ rb_define_method (EmConnection, "associate_callback_target", (VALUE(*)(...))conn_associate_callback_target, 1);
1255
+
1256
+ rb_define_const (EmModule, "TimerFired", INT2NUM(100));
1257
+ rb_define_const (EmModule, "ConnectionData", INT2NUM(101));
1258
+ rb_define_const (EmModule, "ConnectionUnbound", INT2NUM(102));
1259
+ rb_define_const (EmModule, "ConnectionAccepted", INT2NUM(103));
1260
+ rb_define_const (EmModule, "ConnectionCompleted", INT2NUM(104));
1261
+ rb_define_const (EmModule, "LoopbreakSignalled", INT2NUM(105));
1262
+
1263
+ rb_define_const (EmModule, "ConnectionNotifyReadable", INT2NUM(106));
1264
+ rb_define_const (EmModule, "ConnectionNotifyWritable", INT2NUM(107));
1265
+
1266
+ rb_define_const (EmModule, "SslHandshakeCompleted", INT2NUM(108));
1267
+
1268
+ }
1269
+