eventmachine 0.12.6-java → 0.12.8-java

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 (116) hide show
  1. data/{docs/README → README} +21 -13
  2. data/Rakefile +5 -3
  3. data/docs/DEFERRABLES +0 -5
  4. data/docs/INSTALL +2 -4
  5. data/docs/LEGAL +1 -1
  6. data/docs/LIGHTWEIGHT_CONCURRENCY +0 -2
  7. data/docs/PURE_RUBY +0 -2
  8. data/docs/RELEASE_NOTES +0 -2
  9. data/docs/SMTP +0 -7
  10. data/docs/SPAWNED_PROCESSES +0 -4
  11. data/docs/TODO +0 -2
  12. data/eventmachine.gemspec +17 -8
  13. data/examples/ex_channel.rb +43 -0
  14. data/examples/ex_queue.rb +2 -0
  15. data/examples/helper.rb +2 -0
  16. data/ext/cmain.cpp +119 -20
  17. data/ext/cplusplus.cpp +15 -6
  18. data/ext/ed.cpp +303 -93
  19. data/ext/ed.h +49 -22
  20. data/ext/em.cpp +368 -42
  21. data/ext/em.h +43 -6
  22. data/ext/eventmachine.h +21 -8
  23. data/ext/eventmachine_cpp.h +1 -0
  24. data/ext/extconf.rb +4 -0
  25. data/ext/kb.cpp +1 -2
  26. data/ext/pipe.cpp +1 -3
  27. data/ext/project.h +21 -0
  28. data/ext/rubymain.cpp +232 -32
  29. data/ext/ssl.cpp +38 -1
  30. data/ext/ssl.h +5 -1
  31. data/java/src/com/rubyeventmachine/Application.java +7 -3
  32. data/java/src/com/rubyeventmachine/EmReactor.java +16 -1
  33. data/java/src/com/rubyeventmachine/tests/ConnectTest.java +25 -3
  34. data/lib/{protocols → em}/buftok.rb +16 -5
  35. data/lib/em/callback.rb +26 -0
  36. data/lib/em/channel.rb +57 -0
  37. data/lib/em/connection.rb +505 -0
  38. data/lib/em/deferrable.rb +144 -165
  39. data/lib/em/file_watch.rb +54 -0
  40. data/lib/em/future.rb +24 -25
  41. data/lib/em/messages.rb +1 -1
  42. data/lib/em/process_watch.rb +44 -0
  43. data/lib/em/processes.rb +58 -52
  44. data/lib/em/protocols.rb +35 -0
  45. data/lib/em/protocols/header_and_content.rb +138 -0
  46. data/lib/em/protocols/httpclient.rb +263 -0
  47. data/lib/em/protocols/httpclient2.rb +582 -0
  48. data/lib/{protocols → em/protocols}/line_and_text.rb +2 -2
  49. data/lib/em/protocols/linetext2.rb +160 -0
  50. data/lib/{protocols → em/protocols}/memcache.rb +37 -7
  51. data/lib/em/protocols/object_protocol.rb +39 -0
  52. data/lib/em/protocols/postgres3.rb +247 -0
  53. data/lib/em/protocols/saslauth.rb +175 -0
  54. data/lib/em/protocols/smtpclient.rb +331 -0
  55. data/lib/em/protocols/smtpserver.rb +547 -0
  56. data/lib/em/protocols/stomp.rb +200 -0
  57. data/lib/{protocols → em/protocols}/tcptest.rb +21 -25
  58. data/lib/em/queue.rb +61 -0
  59. data/lib/em/spawnable.rb +53 -56
  60. data/lib/em/streamer.rb +92 -74
  61. data/lib/em/timers.rb +55 -0
  62. data/lib/em/version.rb +3 -0
  63. data/lib/eventmachine.rb +1008 -1298
  64. data/lib/evma.rb +1 -1
  65. data/lib/jeventmachine.rb +106 -101
  66. data/lib/pr_eventmachine.rb +47 -36
  67. data/tasks/project.rake +2 -1
  68. data/tests/client.crt +31 -0
  69. data/tests/client.key +51 -0
  70. data/tests/test_attach.rb +18 -0
  71. data/tests/test_basic.rb +108 -54
  72. data/tests/test_channel.rb +63 -0
  73. data/tests/test_connection_count.rb +2 -2
  74. data/tests/test_epoll.rb +109 -110
  75. data/tests/test_errors.rb +36 -36
  76. data/tests/test_exc.rb +22 -25
  77. data/tests/test_file_watch.rb +49 -0
  78. data/tests/test_futures.rb +77 -93
  79. data/tests/test_hc.rb +2 -2
  80. data/tests/test_httpclient.rb +55 -52
  81. data/tests/test_httpclient2.rb +110 -112
  82. data/tests/test_inactivity_timeout.rb +30 -0
  83. data/tests/test_kb.rb +8 -9
  84. data/tests/test_ltp2.rb +274 -277
  85. data/tests/test_next_tick.rb +91 -65
  86. data/tests/test_object_protocol.rb +37 -0
  87. data/tests/test_process_watch.rb +48 -0
  88. data/tests/test_processes.rb +56 -23
  89. data/tests/test_proxy_connection.rb +92 -0
  90. data/tests/test_pure.rb +1 -5
  91. data/tests/test_queue.rb +44 -0
  92. data/tests/test_running.rb +9 -14
  93. data/tests/test_sasl.rb +32 -34
  94. data/tests/test_send_file.rb +175 -176
  95. data/tests/test_servers.rb +37 -41
  96. data/tests/test_smtpserver.rb +47 -55
  97. data/tests/test_spawn.rb +284 -291
  98. data/tests/test_ssl_args.rb +1 -1
  99. data/tests/test_ssl_methods.rb +1 -1
  100. data/tests/test_ssl_verify.rb +82 -0
  101. data/tests/test_timers.rb +81 -88
  102. data/tests/test_ud.rb +0 -7
  103. data/tests/testem.rb +1 -1
  104. metadata +52 -36
  105. data/lib/em/eventable.rb +0 -39
  106. data/lib/eventmachine_version.rb +0 -31
  107. data/lib/protocols/header_and_content.rb +0 -129
  108. data/lib/protocols/httpcli2.rb +0 -803
  109. data/lib/protocols/httpclient.rb +0 -270
  110. data/lib/protocols/linetext2.rb +0 -161
  111. data/lib/protocols/postgres.rb +0 -261
  112. data/lib/protocols/saslauth.rb +0 -179
  113. data/lib/protocols/smtpclient.rb +0 -308
  114. data/lib/protocols/smtpserver.rb +0 -556
  115. data/lib/protocols/stomp.rb +0 -153
  116. data/tests/test_eventables.rb +0 -77
data/ext/em.h CHANGED
@@ -57,9 +57,10 @@ typedef long long Int64;
57
57
  typedef __int64 Int64;
58
58
  #endif
59
59
 
60
- extern time_t gCurrentLoopTime;
60
+ extern Int64 gCurrentLoopTime;
61
61
 
62
62
  class EventableDescriptor;
63
+ class InotifyDescriptor;
63
64
 
64
65
 
65
66
  /********************
@@ -80,9 +81,8 @@ class EventMachine_t
80
81
  void ScheduleHalt();
81
82
  void SignalLoopBreaker();
82
83
  const char *InstallOneshotTimer (int);
83
- const char *ConnectToServer (const char *, int);
84
+ const char *ConnectToServer (const char *, int, const char *, int);
84
85
  const char *ConnectToUnixServer (const char *);
85
- const char *AttachFD (int, bool, bool);
86
86
 
87
87
  const char *CreateTcpServer (const char *, int);
88
88
  const char *OpenDatagramSocket (const char *, int);
@@ -94,7 +94,10 @@ class EventMachine_t
94
94
 
95
95
  void Add (EventableDescriptor*);
96
96
  void Modify (EventableDescriptor*);
97
+
98
+ const char *AttachFD (int, bool, bool);
97
99
  int DetachFD (EventableDescriptor*);
100
+
98
101
  void ArmKqueueWriter (EventableDescriptor*);
99
102
  void ArmKqueueReader (EventableDescriptor*);
100
103
 
@@ -106,15 +109,37 @@ class EventMachine_t
106
109
  int SubprocessExitStatus;
107
110
 
108
111
  int GetConnectionCount();
112
+ float GetHeartbeatInterval();
113
+ int SetHeartbeatInterval(float);
114
+
115
+ const char *WatchFile (const char*);
116
+ void UnwatchFile (int);
117
+ void UnwatchFile (const char*);
118
+
119
+ #ifdef HAVE_KQUEUE
120
+ void _HandleKqueueFileEvent (struct kevent*);
121
+ void _RegisterKqueueFileEvent(int);
122
+ #endif
123
+
124
+ const char *WatchPid (int);
125
+ void UnwatchPid (int);
126
+ void UnwatchPid (const char *);
127
+
128
+ #ifdef HAVE_KQUEUE
129
+ void _HandleKqueuePidEvent (struct kevent*);
130
+ #endif
109
131
 
110
132
  // Temporary:
111
133
  void _UseEpoll();
112
134
  void _UseKqueue();
113
135
 
136
+ bool UsingKqueue() { return bKqueue; }
137
+ bool UsingEpoll() { return bEpoll; }
114
138
 
115
139
  private:
116
140
  bool _RunOnce();
117
141
  bool _RunTimers();
142
+ void _UpdateTime();
118
143
  void _AddNewDescriptors();
119
144
  void _ModifyDescriptors();
120
145
  void _InitializeLoopBreaker();
@@ -127,23 +152,27 @@ class EventMachine_t
127
152
 
128
153
  public:
129
154
  void _ReadLoopBreaker();
155
+ void _ReadInotifyEvents();
130
156
 
131
157
  private:
132
158
  enum {
133
- HeartbeatInterval = 2,
134
- MaxEpollDescriptors = 64*1024
159
+ MaxEpollDescriptors = 64*1024,
160
+ MaxEvents = 4096
135
161
  };
162
+ int HeartbeatInterval;
136
163
  void (*EventCallback)(const char*, int, const char*, int);
137
164
 
138
165
  class Timer_t: public Bindable_t {
139
166
  };
140
167
 
141
168
  multimap<Int64, Timer_t> Timers;
169
+ map<int, Bindable_t*> Files;
170
+ map<int, Bindable_t*> Pids;
142
171
  vector<EventableDescriptor*> Descriptors;
143
172
  vector<EventableDescriptor*> NewDescriptors;
144
173
  set<EventableDescriptor*> ModifiedDescriptors;
145
174
 
146
- time_t NextHeartbeatTime;
175
+ Int64 NextHeartbeatTime;
147
176
 
148
177
  int LoopBreakerReader;
149
178
  int LoopBreakerWriter;
@@ -156,9 +185,17 @@ class EventMachine_t
156
185
  private:
157
186
  bool bEpoll;
158
187
  int epfd; // Epoll file-descriptor
188
+ #ifdef HAVE_EPOLL
189
+ struct epoll_event epoll_events [MaxEvents];
190
+ #endif
159
191
 
160
192
  bool bKqueue;
161
193
  int kqfd; // Kqueue file-descriptor
194
+ #ifdef HAVE_KQUEUE
195
+ struct kevent Karray [MaxEvents];
196
+ #endif
197
+
198
+ InotifyDescriptor *inotify; // pollable descriptor for our inotify instance
162
199
  };
163
200
 
164
201
 
@@ -33,7 +33,9 @@ extern "C" {
33
33
  EM_LOOPBREAK_SIGNAL = 105,
34
34
  EM_CONNECTION_NOTIFY_READABLE = 106,
35
35
  EM_CONNECTION_NOTIFY_WRITABLE = 107,
36
- EM_SSL_HANDSHAKE_COMPLETED = 108
36
+ EM_SSL_HANDSHAKE_COMPLETED = 108,
37
+ EM_SSL_VERIFY = 109,
38
+ EM_PROXY_TARGET_UNBOUND = 110
37
39
 
38
40
  };
39
41
 
@@ -41,7 +43,7 @@ extern "C" {
41
43
  void evma_run_machine();
42
44
  void evma_release_library();
43
45
  const char *evma_install_oneshot_timer (int seconds);
44
- const char *evma_connect_to_server (const char *server, int port);
46
+ const char *evma_connect_to_server (const char *bind_addr, int bind_port, const char *server, int port);
45
47
  const char *evma_connect_to_unix_server (const char *server);
46
48
 
47
49
  const char *evma_attach_fd (int file_descriptor, int read_mode, int write_mode);
@@ -52,11 +54,12 @@ extern "C" {
52
54
  const char *evma_create_unix_domain_server (const char *filename);
53
55
  const char *evma_open_datagram_socket (const char *server, int port);
54
56
  const char *evma_open_keyboard();
55
- void evma_set_tls_parms (const char *binding, const char *privatekey_filename, const char *certchain_filenane);
57
+ void evma_set_tls_parms (const char *binding, const char *privatekey_filename, const char *certchain_filenane, int verify_peer);
56
58
  void evma_start_tls (const char *binding);
57
59
 
58
60
  #ifdef WITH_SSL
59
61
  X509 *evma_get_peer_cert (const char *binding);
62
+ void evma_accept_ssl_peer (const char *binding);
60
63
  #endif
61
64
 
62
65
  int evma_get_peername (const char *binding, struct sockaddr*);
@@ -66,8 +69,8 @@ extern "C" {
66
69
  int evma_get_connection_count();
67
70
  int evma_send_data_to_connection (const char *binding, const char *data, int data_length);
68
71
  int evma_send_datagram (const char *binding, const char *data, int data_length, const char *address, int port);
69
- int evma_get_comm_inactivity_timeout (const char *binding, /*out*/int *value);
70
- int evma_set_comm_inactivity_timeout (const char *binding, /*in,out*/int *value);
72
+ float evma_get_comm_inactivity_timeout (const char *binding);
73
+ int evma_set_comm_inactivity_timeout (const char *binding, float value);
71
74
  int evma_get_outbound_data_size (const char *binding);
72
75
  int evma_send_file_data_to_connection (const char *binding, const char *filename);
73
76
 
@@ -79,15 +82,25 @@ extern "C" {
79
82
  void evma_set_max_timer_count (int);
80
83
  void evma_setuid_string (const char *username);
81
84
  void evma_stop_machine();
85
+ float evma_get_heartbeat_interval();
86
+ int evma_set_heartbeat_interval(float);
82
87
 
83
88
  const char *evma__write_file (const char *filename);
84
89
  const char *evma_popen (char * const*cmd_strings);
85
90
 
91
+ const char *evma_watch_filename (const char *fname);
92
+ void evma_unwatch_filename (const char *sig);
93
+
94
+ const char *evma_watch_pid (int);
95
+ void evma_unwatch_pid (const char *sig);
96
+
97
+ void evma_start_proxy(const char*, const char*);
98
+ void evma_stop_proxy(const char*);
99
+
86
100
  int evma_set_rlimit_nofile (int n_files);
87
101
 
88
- // Temporary:
89
- void evma__epoll();
90
- void evma__kqueue();
102
+ void evma_set_epoll (int use);
103
+ void evma_set_kqueue (int use);
91
104
 
92
105
  #if __cplusplus
93
106
  }
@@ -63,6 +63,7 @@ namespace EM {
63
63
  virtual ~Connection() {}
64
64
 
65
65
  virtual void Connect (const char*, int);
66
+ virtual void BindConnect (const char *, int, const char*, int);
66
67
 
67
68
  void SendData (const char *data);
68
69
  void SendData (const char *data, int length);
@@ -15,6 +15,9 @@ end
15
15
  add_define 'BUILD_FOR_RUBY'
16
16
  add_define 'HAVE_RBTRAP' if have_var('rb_trap_immediate', ['ruby.h', 'rubysig.h'])
17
17
  add_define "HAVE_TBR" if have_func('rb_thread_blocking_region')# and have_macro('RUBY_UBF_IO', 'ruby.h')
18
+ add_define "HAVE_INOTIFY" if inotify = have_func('inotify_init', 'sys/inotify.h')
19
+ add_define "HAVE_OLD_INOTIFY" if !inotify && have_macro('__NR_inotify_init', 'sys/syscall.h')
20
+ add_define 'HAVE_WRITEV' if have_func('writev', 'sys/uio.h')
18
21
 
19
22
  # Minor platform details between *nix and Windows:
20
23
 
@@ -59,6 +62,7 @@ when /solaris/
59
62
  # on Unix we need a g++ link, not gcc.
60
63
  CONFIG['LDSHARED'] = "$(CXX) -shared"
61
64
  end
65
+
62
66
  when /openbsd/
63
67
  # OpenBSD branch contributed by Guillaume Sellier.
64
68
 
data/ext/kb.cpp CHANGED
@@ -77,6 +77,5 @@ void KeyboardDescriptor::Read()
77
77
  {
78
78
  char c;
79
79
  read (GetSocket(), &c, 1);
80
- if (EventCallback)
81
- (*EventCallback)(GetBinding().c_str(), EM_CONNECTION_READ, &c, 1);
80
+ _GenericInboundDispatch(&c, 1);
82
81
  }
@@ -164,7 +164,6 @@ void PipeDescriptor::Read()
164
164
 
165
165
  if (r > 0) {
166
166
  total_bytes_read += r;
167
- LastRead = gCurrentLoopTime;
168
167
 
169
168
  // Add a null-terminator at the the end of the buffer
170
169
  // that we will send to the callback.
@@ -173,8 +172,7 @@ void PipeDescriptor::Read()
173
172
  // the option to do some things faster. Additionally it's
174
173
  // a security guard against buffer overflows.
175
174
  readbuffer [r] = 0;
176
- if (EventCallback)
177
- (*EventCallback)(GetBinding().c_str(), EM_CONNECTION_READ, readbuffer, r);
175
+ _GenericInboundDispatch(readbuffer, r);
178
176
  }
179
177
  else if (r == 0) {
180
178
  break;
@@ -102,6 +102,27 @@ using namespace std;
102
102
  #include <sys/queue.h>
103
103
  #endif
104
104
 
105
+ #ifdef HAVE_INOTIFY
106
+ #include <sys/inotify.h>
107
+ #endif
108
+
109
+ #ifdef HAVE_OLD_INOTIFY
110
+ #include <sys/syscall.h>
111
+ #include <linux/inotify.h>
112
+ static inline int inotify_init (void) { return syscall (__NR_inotify_init); }
113
+ static inline int inotify_add_watch (int fd, const char *name, __u32 mask) { return syscall (__NR_inotify_add_watch, fd, name, mask); }
114
+ static inline int inotify_rm_watch (int fd, __u32 wd) { return syscall (__NR_inotify_rm_watch, fd, wd); }
115
+ #define HAVE_INOTIFY 1
116
+ #endif
117
+
118
+ #ifdef HAVE_INOTIFY
119
+ #define INOTIFY_EVENT_SIZE (sizeof(struct inotify_event))
120
+ #endif
121
+
122
+ #ifdef HAVE_WRITEV
123
+ #include <sys/uio.h>
124
+ #endif
125
+
105
126
  #include "binder.h"
106
127
  #include "em.h"
107
128
  #include "epoll.h"
@@ -21,7 +21,9 @@ See the file COPYING for complete licensing information.
21
21
  #include "eventmachine.h"
22
22
  #include <ruby.h>
23
23
 
24
-
24
+ #ifndef RFLOAT_VALUE
25
+ #define RFLOAT_VALUE(arg) RFLOAT(arg)->value
26
+ #endif
25
27
 
26
28
  /*******
27
29
  Statics
@@ -43,8 +45,10 @@ static VALUE Intern_delete;
43
45
  static VALUE Intern_call;
44
46
  static VALUE Intern_receive_data;
45
47
  static VALUE Intern_ssl_handshake_completed;
48
+ static VALUE Intern_ssl_verify_peer;
46
49
  static VALUE Intern_notify_readable;
47
50
  static VALUE Intern_notify_writable;
51
+ static VALUE Intern_proxy_target_unbound;
48
52
 
49
53
  static VALUE rb_cProcStatus;
50
54
 
@@ -93,10 +97,15 @@ static void event_callback (struct em_event* e)
93
97
  else if (a2 == EM_TIMER_FIRED) {
94
98
  VALUE t = rb_ivar_get (EmModule, Intern_at_timers);
95
99
  VALUE q = rb_funcall (t, Intern_delete, 1, rb_str_new(a3, a4));
96
- if (q == Qnil)
100
+ if (q == Qnil) {
97
101
  rb_raise (EM_eUnknownTimerFired, "no such timer: %s", a1);
98
- rb_funcall (q, Intern_call, 0);
102
+ } else if (q == Qfalse) {
103
+ /* Timer Canceled */
104
+ } else {
105
+ rb_funcall (q, Intern_call, 0);
106
+ }
99
107
  }
108
+ #ifdef WITH_SSL
100
109
  else if (a2 == EM_SSL_HANDSHAKE_COMPLETED) {
101
110
  VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
102
111
  VALUE q = rb_hash_aref (t, rb_str_new2(a1));
@@ -104,6 +113,23 @@ static void event_callback (struct em_event* e)
104
113
  rb_raise (EM_eConnectionNotBound, "unknown connection: %s", a1);
105
114
  rb_funcall (q, Intern_ssl_handshake_completed, 0);
106
115
  }
116
+ else if (a2 == EM_SSL_VERIFY) {
117
+ VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
118
+ VALUE q = rb_hash_aref (t, rb_str_new2(a1));
119
+ if (q == Qnil)
120
+ rb_raise (EM_eConnectionNotBound, "unknown connection: %s", a1);
121
+ VALUE r = rb_funcall (q, Intern_ssl_verify_peer, 1, rb_str_new(a3, a4));
122
+ if (RTEST(r))
123
+ evma_accept_ssl_peer (a1);
124
+ }
125
+ #endif
126
+ else if (a2 == EM_PROXY_TARGET_UNBOUND) {
127
+ VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
128
+ VALUE q = rb_hash_aref (t, rb_str_new2(a1));
129
+ if (q == Qnil)
130
+ rb_raise (EM_eConnectionNotBound, "unknown connection: %s", a1);
131
+ rb_funcall (q, Intern_proxy_target_unbound, 0);
132
+ }
107
133
  else
108
134
  rb_funcall (EmModule, Intern_event_callback, 3, rb_str_new2(a1), (a2 << 1) | 1, rb_str_new(a3,a4));
109
135
  }
@@ -234,20 +260,20 @@ static VALUE t_start_tls (VALUE self, VALUE signature)
234
260
  t_set_tls_parms
235
261
  ***************/
236
262
 
237
- static VALUE t_set_tls_parms (VALUE self, VALUE signature, VALUE privkeyfile, VALUE certchainfile)
263
+ static VALUE t_set_tls_parms (VALUE self, VALUE signature, VALUE privkeyfile, VALUE certchainfile, VALUE verify_peer)
238
264
  {
239
265
  /* set_tls_parms takes a series of positional arguments for specifying such things
240
266
  * as private keys and certificate chains.
241
267
  * It's expected that the parameter list will grow as we add more supported features.
242
268
  * ALL of these parameters are optional, and can be specified as empty or NULL strings.
243
269
  */
244
- evma_set_tls_parms (StringValuePtr (signature), StringValuePtr (privkeyfile), StringValuePtr (certchainfile) );
270
+ evma_set_tls_parms (StringValuePtr (signature), StringValuePtr (privkeyfile), StringValuePtr (certchainfile), (verify_peer == Qtrue ? 1 : 0));
245
271
  return Qnil;
246
272
  }
247
273
 
248
- /***********
274
+ /***************
249
275
  t_get_peer_cert
250
- ***********/
276
+ ***************/
251
277
 
252
278
  static VALUE t_get_peer_cert (VALUE self, VALUE signature)
253
279
  {
@@ -352,10 +378,7 @@ t_get_comm_inactivity_timeout
352
378
 
353
379
  static VALUE t_get_comm_inactivity_timeout (VALUE self, VALUE signature)
354
380
  {
355
- int timeout;
356
- if (evma_get_comm_inactivity_timeout (StringValuePtr (signature), &timeout))
357
- return INT2FIX (timeout);
358
- return Qnil;
381
+ return rb_float_new(evma_get_comm_inactivity_timeout(StringValuePtr(signature)));
359
382
  }
360
383
 
361
384
  /*****************************
@@ -364,10 +387,10 @@ t_set_comm_inactivity_timeout
364
387
 
365
388
  static VALUE t_set_comm_inactivity_timeout (VALUE self, VALUE signature, VALUE timeout)
366
389
  {
367
- int ti = FIX2INT (timeout);
368
- if (evma_set_comm_inactivity_timeout (StringValuePtr (signature), &ti));
390
+ float ti = RFLOAT_VALUE(timeout);
391
+ if (evma_set_comm_inactivity_timeout (StringValuePtr (signature), ti));
369
392
  return Qtrue;
370
- return Qnil;
393
+ return Qfalse;
371
394
  }
372
395
 
373
396
 
@@ -414,12 +437,33 @@ static VALUE t_connect_server (VALUE self, VALUE server, VALUE port)
414
437
  // Specifically, if the value of port comes in as a string rather than an integer,
415
438
  // NUM2INT will throw a type error, but FIX2INT will generate garbage.
416
439
 
417
- const char *f = evma_connect_to_server (StringValuePtr(server), NUM2INT(port));
440
+ const char *f = evma_connect_to_server (NULL, 0, StringValuePtr(server), NUM2INT(port));
418
441
  if (!f || !*f)
419
442
  rb_raise (rb_eRuntimeError, "no connection");
420
443
  return rb_str_new2 (f);
421
444
  }
422
445
 
446
+ /*********************
447
+ t_bind_connect_server
448
+ *********************/
449
+
450
+ static VALUE t_bind_connect_server (VALUE self, VALUE bind_addr, VALUE bind_port, VALUE server, VALUE port)
451
+ {
452
+ // Avoid FIX2INT in this case, because it doesn't deal with type errors properly.
453
+ // Specifically, if the value of port comes in as a string rather than an integer,
454
+ // NUM2INT will throw a type error, but FIX2INT will generate garbage.
455
+
456
+ const char *f;
457
+ try {
458
+ f = evma_connect_to_server (StringValuePtr(bind_addr), NUM2INT(bind_port), StringValuePtr(server), NUM2INT(port));
459
+ if (!f || !*f)
460
+ rb_raise (rb_eRuntimeError, "no connection");
461
+ } catch (std::runtime_error e) {
462
+ rb_sys_fail(e.what());
463
+ }
464
+ return rb_str_new2 (f);
465
+ }
466
+
423
467
  /*********************
424
468
  t_connect_unix_server
425
469
  *********************/
@@ -609,17 +653,56 @@ static VALUE t_read_keyboard (VALUE self)
609
653
  }
610
654
 
611
655
 
612
- /********
613
- t__epoll
614
- ********/
656
+ /****************
657
+ t_watch_filename
658
+ ****************/
615
659
 
616
- static VALUE t__epoll (VALUE self)
660
+ static VALUE t_watch_filename (VALUE self, VALUE fname)
661
+ {
662
+ try {
663
+ return rb_str_new2(evma_watch_filename(StringValuePtr(fname)));
664
+ } catch (std::runtime_error e) {
665
+ rb_sys_fail(e.what());
666
+ }
667
+ }
668
+
669
+
670
+ /******************
671
+ t_unwatch_filename
672
+ ******************/
673
+
674
+ static VALUE t_unwatch_filename (VALUE self, VALUE sig)
617
675
  {
618
- // Temporary.
619
- evma__epoll();
676
+ evma_unwatch_filename(StringValuePtr(sig));
620
677
  return Qnil;
621
678
  }
622
679
 
680
+
681
+ /***********
682
+ t_watch_pid
683
+ ***********/
684
+
685
+ static VALUE t_watch_pid (VALUE self, VALUE pid)
686
+ {
687
+ try {
688
+ return rb_str_new2(evma_watch_pid(NUM2INT(pid)));
689
+ } catch (std::runtime_error e) {
690
+ rb_sys_fail(e.what());
691
+ }
692
+ }
693
+
694
+
695
+ /*************
696
+ t_unwatch_pid
697
+ *************/
698
+
699
+ static VALUE t_unwatch_pid (VALUE self, VALUE sig)
700
+ {
701
+ evma_unwatch_pid(StringValuePtr(sig));
702
+ return Qnil;
703
+ }
704
+
705
+
623
706
  /**********
624
707
  t__epoll_p
625
708
  **********/
@@ -633,18 +716,33 @@ static VALUE t__epoll_p (VALUE self)
633
716
  #endif
634
717
  }
635
718
 
719
+ /********
720
+ t__epoll
721
+ ********/
636
722
 
637
- /*********
638
- t__kqueue
639
- *********/
723
+ static VALUE t__epoll (VALUE self)
724
+ {
725
+ if (t__epoll_p(self) == Qfalse)
726
+ return Qfalse;
640
727
 
641
- static VALUE t__kqueue (VALUE self)
728
+ evma_set_epoll (1);
729
+ return Qtrue;
730
+ }
731
+
732
+ /***********
733
+ t__epoll_set
734
+ ***********/
735
+
736
+ static VALUE t__epoll_set (VALUE self, VALUE val)
642
737
  {
643
- // Temporary.
644
- evma__kqueue();
645
- return Qnil;
738
+ if (t__epoll_p(self) == Qfalse)
739
+ return Qfalse;
740
+
741
+ evma_set_epoll (val == Qtrue ? 1 : 0);
742
+ return val;
646
743
  }
647
744
 
745
+
648
746
  /***********
649
747
  t__kqueue_p
650
748
  ***********/
@@ -658,6 +756,46 @@ static VALUE t__kqueue_p (VALUE self)
658
756
  #endif
659
757
  }
660
758
 
759
+ /*********
760
+ t__kqueue
761
+ *********/
762
+
763
+ static VALUE t__kqueue (VALUE self)
764
+ {
765
+ if (t__kqueue_p(self) == Qfalse)
766
+ return Qfalse;
767
+
768
+ evma_set_kqueue (1);
769
+ return Qtrue;
770
+ }
771
+
772
+ /*************
773
+ t__kqueue_set
774
+ *************/
775
+
776
+ static VALUE t__kqueue_set (VALUE self, VALUE val)
777
+ {
778
+ if (t__kqueue_p(self) == Qfalse)
779
+ return Qfalse;
780
+
781
+ evma_set_kqueue (val == Qtrue ? 1 : 0);
782
+ return val;
783
+ }
784
+
785
+
786
+ /********
787
+ t__ssl_p
788
+ ********/
789
+
790
+ static VALUE t__ssl_p (VALUE self)
791
+ {
792
+ #ifdef WITH_SSL
793
+ return Qtrue;
794
+ #else
795
+ return Qfalse;
796
+ #endif
797
+ }
798
+
661
799
 
662
800
  /****************
663
801
  t_send_file_data
@@ -739,6 +877,51 @@ static VALUE t_get_loop_time (VALUE self)
739
877
  }
740
878
 
741
879
 
880
+ /*************
881
+ t_start_proxy
882
+ **************/
883
+
884
+ static VALUE t_start_proxy (VALUE self, VALUE from, VALUE to)
885
+ {
886
+ evma_start_proxy(StringValuePtr(from), StringValuePtr(to));
887
+ return Qnil;
888
+ }
889
+
890
+
891
+ /************
892
+ t_stop_proxy
893
+ *************/
894
+
895
+ static VALUE t_stop_proxy (VALUE self, VALUE from)
896
+ {
897
+ evma_stop_proxy(StringValuePtr(from));
898
+ return Qnil;
899
+ }
900
+
901
+
902
+ /************************
903
+ t_get_heartbeat_interval
904
+ *************************/
905
+
906
+ static VALUE t_get_heartbeat_interval (VALUE self)
907
+ {
908
+ return rb_float_new(evma_get_heartbeat_interval());
909
+ }
910
+
911
+
912
+ /************************
913
+ t_set_heartbeat_interval
914
+ *************************/
915
+
916
+ static VALUE t_set_heartbeat_interval (VALUE self, VALUE interval)
917
+ {
918
+ float iv = RFLOAT_VALUE(interval);
919
+ if (evma_set_heartbeat_interval(iv))
920
+ return Qtrue;
921
+ return Qfalse;
922
+ }
923
+
924
+
742
925
  /*********************
743
926
  Init_rubyeventmachine
744
927
  *********************/
@@ -761,8 +944,10 @@ extern "C" void Init_rubyeventmachine()
761
944
  Intern_call = rb_intern ("call");
762
945
  Intern_receive_data = rb_intern ("receive_data");
763
946
  Intern_ssl_handshake_completed = rb_intern ("ssl_handshake_completed");
947
+ Intern_ssl_verify_peer = rb_intern ("ssl_verify_peer");
764
948
  Intern_notify_readable = rb_intern ("notify_readable");
765
949
  Intern_notify_writable = rb_intern ("notify_writable");
950
+ Intern_proxy_target_unbound = rb_intern ("proxy_target_unbound");
766
951
 
767
952
  // INCOMPLETE, we need to define class Connections inside module EventMachine
768
953
  // run_machine and run_machine_without_threads are now identical.
@@ -781,7 +966,7 @@ extern "C" void Init_rubyeventmachine()
781
966
  rb_define_module_function (EmModule, "start_tcp_server", (VALUE(*)(...))t_start_server, 2);
782
967
  rb_define_module_function (EmModule, "stop_tcp_server", (VALUE(*)(...))t_stop_server, 1);
783
968
  rb_define_module_function (EmModule, "start_unix_server", (VALUE(*)(...))t_start_unix_server, 1);
784
- rb_define_module_function (EmModule, "set_tls_parms", (VALUE(*)(...))t_set_tls_parms, 3);
969
+ rb_define_module_function (EmModule, "set_tls_parms", (VALUE(*)(...))t_set_tls_parms, 4);
785
970
  rb_define_module_function (EmModule, "start_tls", (VALUE(*)(...))t_start_tls, 1);
786
971
  rb_define_module_function (EmModule, "get_peer_cert", (VALUE(*)(...))t_get_peer_cert, 1);
787
972
  rb_define_module_function (EmModule, "send_data", (VALUE(*)(...))t_send_data, 3);
@@ -789,11 +974,21 @@ extern "C" void Init_rubyeventmachine()
789
974
  rb_define_module_function (EmModule, "close_connection", (VALUE(*)(...))t_close_connection, 2);
790
975
  rb_define_module_function (EmModule, "report_connection_error_status", (VALUE(*)(...))t_report_connection_error_status, 1);
791
976
  rb_define_module_function (EmModule, "connect_server", (VALUE(*)(...))t_connect_server, 2);
977
+ rb_define_module_function (EmModule, "bind_connect_server", (VALUE(*)(...))t_bind_connect_server, 4);
792
978
  rb_define_module_function (EmModule, "connect_unix_server", (VALUE(*)(...))t_connect_unix_server, 1);
793
979
 
794
980
  rb_define_module_function (EmModule, "attach_fd", (VALUE (*)(...))t_attach_fd, 3);
795
981
  rb_define_module_function (EmModule, "detach_fd", (VALUE (*)(...))t_detach_fd, 1);
796
982
 
983
+ rb_define_module_function (EmModule, "start_proxy", (VALUE (*)(...))t_start_proxy, 2);
984
+ rb_define_module_function (EmModule, "stop_proxy", (VALUE (*)(...))t_stop_proxy, 1);
985
+
986
+ rb_define_module_function (EmModule, "watch_filename", (VALUE (*)(...))t_watch_filename, 1);
987
+ rb_define_module_function (EmModule, "unwatch_filename", (VALUE (*)(...))t_unwatch_filename, 1);
988
+
989
+ rb_define_module_function (EmModule, "watch_pid", (VALUE (*)(...))t_watch_pid, 1);
990
+ rb_define_module_function (EmModule, "unwatch_pid", (VALUE (*)(...))t_unwatch_pid, 1);
991
+
797
992
  rb_define_module_function (EmModule, "current_time", (VALUE(*)(...))t_get_loop_time, 0);
798
993
 
799
994
  rb_define_module_function (EmModule, "open_udp_socket", (VALUE(*)(...))t_open_udp_socket, 2);
@@ -808,6 +1003,8 @@ extern "C" void Init_rubyeventmachine()
808
1003
  rb_define_module_function (EmModule, "setuid_string", (VALUE(*)(...))t_setuid_string, 1);
809
1004
  rb_define_module_function (EmModule, "invoke_popen", (VALUE(*)(...))t_invoke_popen, 1);
810
1005
  rb_define_module_function (EmModule, "send_file_data", (VALUE(*)(...))t_send_file_data, 2);
1006
+ rb_define_module_function (EmModule, "get_heartbeat_interval", (VALUE(*)(...))t_get_heartbeat_interval, 0);
1007
+ rb_define_module_function (EmModule, "set_heartbeat_interval", (VALUE(*)(...))t_set_heartbeat_interval, 1);
811
1008
 
812
1009
  // Provisional:
813
1010
  rb_define_module_function (EmModule, "_write_file", (VALUE(*)(...))t__write_file, 1);
@@ -821,13 +1018,16 @@ extern "C" void Init_rubyeventmachine()
821
1018
  rb_define_module_function (EmModule, "set_rlimit_nofile", (VALUE(*)(...))t_set_rlimit_nofile, 1);
822
1019
  rb_define_module_function (EmModule, "get_connection_count", (VALUE(*)(...))t_get_connection_count, 0);
823
1020
 
824
- // Temporary:
825
1021
  rb_define_module_function (EmModule, "epoll", (VALUE(*)(...))t__epoll, 0);
826
- rb_define_module_function (EmModule, "kqueue", (VALUE(*)(...))t__kqueue, 0);
827
-
1022
+ rb_define_module_function (EmModule, "epoll=", (VALUE(*)(...))t__epoll_set, 1);
828
1023
  rb_define_module_function (EmModule, "epoll?", (VALUE(*)(...))t__epoll_p, 0);
1024
+
1025
+ rb_define_module_function (EmModule, "kqueue", (VALUE(*)(...))t__kqueue, 0);
1026
+ rb_define_module_function (EmModule, "kqueue=", (VALUE(*)(...))t__kqueue_set, 1);
829
1027
  rb_define_module_function (EmModule, "kqueue?", (VALUE(*)(...))t__kqueue_p, 0);
830
1028
 
1029
+ rb_define_module_function (EmModule, "ssl?", (VALUE(*)(...))t__ssl_p, 0);
1030
+
831
1031
  rb_define_method (EmConnection, "get_outbound_data_size", (VALUE(*)(...))conn_get_outbound_data_size, 0);
832
1032
  rb_define_method (EmConnection, "associate_callback_target", (VALUE(*)(...))conn_associate_callback_target, 1);
833
1033