crusher-eventmachine 0.12.11

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