eventmachine-le 1.1.0.beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
+