ext/rubymain.cpp in eventmachine-eventmachine-0.12.7 vs ext/rubymain.cpp in eventmachine-eventmachine-0.12.8
- old
+ new
@@ -19,12 +19,14 @@
#include "project.h"
#include "eventmachine.h"
#include <ruby.h>
+#ifndef RFLOAT_VALUE
+#define RFLOAT_VALUE(arg) RFLOAT(arg)->value
+#endif
-
/*******
Statics
*******/
static VALUE EmModule;
@@ -41,12 +43,14 @@
static VALUE Intern_run_deferred_callbacks;
static VALUE Intern_delete;
static VALUE Intern_call;
static VALUE Intern_receive_data;
static VALUE Intern_ssl_handshake_completed;
+static VALUE Intern_ssl_verify_peer;
static VALUE Intern_notify_readable;
static VALUE Intern_notify_writable;
+static VALUE Intern_proxy_target_unbound;
static VALUE rb_cProcStatus;
struct em_event {
const char *a1;
@@ -91,21 +95,43 @@
rb_funcall (EmModule, Intern_run_deferred_callbacks, 0);
}
else if (a2 == EM_TIMER_FIRED) {
VALUE t = rb_ivar_get (EmModule, Intern_at_timers);
VALUE q = rb_funcall (t, Intern_delete, 1, rb_str_new(a3, a4));
- if (q == Qnil)
+ if (q == Qnil) {
rb_raise (EM_eUnknownTimerFired, "no such timer: %s", a1);
- rb_funcall (q, Intern_call, 0);
+ } else if (q == Qfalse) {
+ /* Timer Canceled */
+ } else {
+ rb_funcall (q, Intern_call, 0);
+ }
}
+ #ifdef WITH_SSL
else if (a2 == EM_SSL_HANDSHAKE_COMPLETED) {
VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
VALUE q = rb_hash_aref (t, rb_str_new2(a1));
if (q == Qnil)
rb_raise (EM_eConnectionNotBound, "unknown connection: %s", a1);
rb_funcall (q, Intern_ssl_handshake_completed, 0);
}
+ else if (a2 == EM_SSL_VERIFY) {
+ VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
+ VALUE q = rb_hash_aref (t, rb_str_new2(a1));
+ if (q == Qnil)
+ rb_raise (EM_eConnectionNotBound, "unknown connection: %s", a1);
+ VALUE r = rb_funcall (q, Intern_ssl_verify_peer, 1, rb_str_new(a3, a4));
+ if (RTEST(r))
+ evma_accept_ssl_peer (a1);
+ }
+ #endif
+ else if (a2 == EM_PROXY_TARGET_UNBOUND) {
+ VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
+ VALUE q = rb_hash_aref (t, rb_str_new2(a1));
+ if (q == Qnil)
+ rb_raise (EM_eConnectionNotBound, "unknown connection: %s", a1);
+ rb_funcall (q, Intern_proxy_target_unbound, 0);
+ }
else
rb_funcall (EmModule, Intern_event_callback, 3, rb_str_new2(a1), (a2 << 1) | 1, rb_str_new(a3,a4));
}
/*******************
@@ -232,24 +258,24 @@
/***************
t_set_tls_parms
***************/
-static VALUE t_set_tls_parms (VALUE self, VALUE signature, VALUE privkeyfile, VALUE certchainfile)
+static VALUE t_set_tls_parms (VALUE self, VALUE signature, VALUE privkeyfile, VALUE certchainfile, VALUE verify_peer)
{
/* set_tls_parms takes a series of positional arguments for specifying such things
* as private keys and certificate chains.
* It's expected that the parameter list will grow as we add more supported features.
* ALL of these parameters are optional, and can be specified as empty or NULL strings.
*/
- evma_set_tls_parms (StringValuePtr (signature), StringValuePtr (privkeyfile), StringValuePtr (certchainfile) );
+ evma_set_tls_parms (StringValuePtr (signature), StringValuePtr (privkeyfile), StringValuePtr (certchainfile), (verify_peer == Qtrue ? 1 : 0));
return Qnil;
}
-/***********
+/***************
t_get_peer_cert
-***********/
+***************/
static VALUE t_get_peer_cert (VALUE self, VALUE signature)
{
VALUE ret = Qnil;
@@ -350,26 +376,23 @@
t_get_comm_inactivity_timeout
*****************************/
static VALUE t_get_comm_inactivity_timeout (VALUE self, VALUE signature)
{
- int timeout;
- if (evma_get_comm_inactivity_timeout (StringValuePtr (signature), &timeout))
- return INT2FIX (timeout);
- return Qnil;
+ return rb_float_new(evma_get_comm_inactivity_timeout(StringValuePtr(signature)));
}
/*****************************
t_set_comm_inactivity_timeout
*****************************/
static VALUE t_set_comm_inactivity_timeout (VALUE self, VALUE signature, VALUE timeout)
{
- int ti = FIX2INT (timeout);
- if (evma_set_comm_inactivity_timeout (StringValuePtr (signature), &ti));
+ float ti = RFLOAT_VALUE(timeout);
+ if (evma_set_comm_inactivity_timeout (StringValuePtr (signature), ti));
return Qtrue;
- return Qnil;
+ return Qfalse;
}
/***************
t_send_datagram
@@ -412,17 +435,38 @@
{
// Avoid FIX2INT in this case, because it doesn't deal with type errors properly.
// Specifically, if the value of port comes in as a string rather than an integer,
// NUM2INT will throw a type error, but FIX2INT will generate garbage.
- const char *f = evma_connect_to_server (StringValuePtr(server), NUM2INT(port));
+ const char *f = evma_connect_to_server (NULL, 0, StringValuePtr(server), NUM2INT(port));
if (!f || !*f)
rb_raise (rb_eRuntimeError, "no connection");
return rb_str_new2 (f);
}
/*********************
+t_bind_connect_server
+*********************/
+
+static VALUE t_bind_connect_server (VALUE self, VALUE bind_addr, VALUE bind_port, VALUE server, VALUE port)
+{
+ // Avoid FIX2INT in this case, because it doesn't deal with type errors properly.
+ // Specifically, if the value of port comes in as a string rather than an integer,
+ // NUM2INT will throw a type error, but FIX2INT will generate garbage.
+
+ const char *f;
+ try {
+ f = evma_connect_to_server (StringValuePtr(bind_addr), NUM2INT(bind_port), StringValuePtr(server), NUM2INT(port));
+ if (!f || !*f)
+ rb_raise (rb_eRuntimeError, "no connection");
+ } catch (std::runtime_error e) {
+ rb_sys_fail(e.what());
+ }
+ return rb_str_new2 (f);
+}
+
+/*********************
t_connect_unix_server
*********************/
static VALUE t_connect_unix_server (VALUE self, VALUE serversocket)
{
@@ -607,21 +651,60 @@
rb_raise (rb_eRuntimeError, "no keyboard reader");
return rb_str_new2 (f);
}
-/********
-t__epoll
-********/
+/****************
+t_watch_filename
+****************/
-static VALUE t__epoll (VALUE self)
+static VALUE t_watch_filename (VALUE self, VALUE fname)
{
- // Temporary.
- evma__epoll();
+ try {
+ return rb_str_new2(evma_watch_filename(StringValuePtr(fname)));
+ } catch (std::runtime_error e) {
+ rb_sys_fail(e.what());
+ }
+}
+
+
+/******************
+t_unwatch_filename
+******************/
+
+static VALUE t_unwatch_filename (VALUE self, VALUE sig)
+{
+ evma_unwatch_filename(StringValuePtr(sig));
return Qnil;
}
+
+/***********
+t_watch_pid
+***********/
+
+static VALUE t_watch_pid (VALUE self, VALUE pid)
+{
+ try {
+ return rb_str_new2(evma_watch_pid(NUM2INT(pid)));
+ } catch (std::runtime_error e) {
+ rb_sys_fail(e.what());
+ }
+}
+
+
+/*************
+t_unwatch_pid
+*************/
+
+static VALUE t_unwatch_pid (VALUE self, VALUE sig)
+{
+ evma_unwatch_pid(StringValuePtr(sig));
+ return Qnil;
+}
+
+
/**********
t__epoll_p
**********/
static VALUE t__epoll_p (VALUE self)
@@ -631,22 +714,37 @@
#else
return Qfalse;
#endif
}
+/********
+t__epoll
+********/
-/*********
-t__kqueue
-*********/
+static VALUE t__epoll (VALUE self)
+{
+ if (t__epoll_p(self) == Qfalse)
+ return Qfalse;
-static VALUE t__kqueue (VALUE self)
+ evma_set_epoll (1);
+ return Qtrue;
+}
+
+/***********
+t__epoll_set
+***********/
+
+static VALUE t__epoll_set (VALUE self, VALUE val)
{
- // Temporary.
- evma__kqueue();
- return Qnil;
+ if (t__epoll_p(self) == Qfalse)
+ return Qfalse;
+
+ evma_set_epoll (val == Qtrue ? 1 : 0);
+ return val;
}
+
/***********
t__kqueue_p
***********/
static VALUE t__kqueue_p (VALUE self)
@@ -656,11 +754,51 @@
#else
return Qfalse;
#endif
}
+/*********
+t__kqueue
+*********/
+static VALUE t__kqueue (VALUE self)
+{
+ if (t__kqueue_p(self) == Qfalse)
+ return Qfalse;
+
+ evma_set_kqueue (1);
+ return Qtrue;
+}
+
+/*************
+t__kqueue_set
+*************/
+
+static VALUE t__kqueue_set (VALUE self, VALUE val)
+{
+ if (t__kqueue_p(self) == Qfalse)
+ return Qfalse;
+
+ evma_set_kqueue (val == Qtrue ? 1 : 0);
+ return val;
+}
+
+
+/********
+t__ssl_p
+********/
+
+static VALUE t__ssl_p (VALUE self)
+{
+ #ifdef WITH_SSL
+ return Qtrue;
+ #else
+ return Qfalse;
+ #endif
+}
+
+
/****************
t_send_file_data
****************/
static VALUE t_send_file_data (VALUE self, VALUE signature, VALUE filename)
@@ -737,10 +875,55 @@
}
return Qnil;
}
+/*************
+t_start_proxy
+**************/
+
+static VALUE t_start_proxy (VALUE self, VALUE from, VALUE to)
+{
+ evma_start_proxy(StringValuePtr(from), StringValuePtr(to));
+ return Qnil;
+}
+
+
+/************
+t_stop_proxy
+*************/
+
+static VALUE t_stop_proxy (VALUE self, VALUE from)
+{
+ evma_stop_proxy(StringValuePtr(from));
+ return Qnil;
+}
+
+
+/************************
+t_get_heartbeat_interval
+*************************/
+
+static VALUE t_get_heartbeat_interval (VALUE self)
+{
+ return rb_float_new(evma_get_heartbeat_interval());
+}
+
+
+/************************
+t_set_heartbeat_interval
+*************************/
+
+static VALUE t_set_heartbeat_interval (VALUE self, VALUE interval)
+{
+ float iv = RFLOAT_VALUE(interval);
+ if (evma_set_heartbeat_interval(iv))
+ return Qtrue;
+ return Qfalse;
+}
+
+
/*********************
Init_rubyeventmachine
*********************/
extern "C" void Init_rubyeventmachine()
@@ -759,12 +942,14 @@
Intern_run_deferred_callbacks = rb_intern ("run_deferred_callbacks");
Intern_delete = rb_intern ("delete");
Intern_call = rb_intern ("call");
Intern_receive_data = rb_intern ("receive_data");
Intern_ssl_handshake_completed = rb_intern ("ssl_handshake_completed");
+ Intern_ssl_verify_peer = rb_intern ("ssl_verify_peer");
Intern_notify_readable = rb_intern ("notify_readable");
Intern_notify_writable = rb_intern ("notify_writable");
+ Intern_proxy_target_unbound = rb_intern ("proxy_target_unbound");
// INCOMPLETE, we need to define class Connections inside module EventMachine
// run_machine and run_machine_without_threads are now identical.
// Must deprecate the without_threads variant.
EmModule = rb_define_module ("EventMachine");
@@ -779,23 +964,33 @@
rb_define_module_function (EmModule, "run_machine_without_threads", (VALUE(*)(...))t_run_machine_without_threads, 0);
rb_define_module_function (EmModule, "add_oneshot_timer", (VALUE(*)(...))t_add_oneshot_timer, 1);
rb_define_module_function (EmModule, "start_tcp_server", (VALUE(*)(...))t_start_server, 2);
rb_define_module_function (EmModule, "stop_tcp_server", (VALUE(*)(...))t_stop_server, 1);
rb_define_module_function (EmModule, "start_unix_server", (VALUE(*)(...))t_start_unix_server, 1);
- rb_define_module_function (EmModule, "set_tls_parms", (VALUE(*)(...))t_set_tls_parms, 3);
+ rb_define_module_function (EmModule, "set_tls_parms", (VALUE(*)(...))t_set_tls_parms, 4);
rb_define_module_function (EmModule, "start_tls", (VALUE(*)(...))t_start_tls, 1);
rb_define_module_function (EmModule, "get_peer_cert", (VALUE(*)(...))t_get_peer_cert, 1);
rb_define_module_function (EmModule, "send_data", (VALUE(*)(...))t_send_data, 3);
rb_define_module_function (EmModule, "send_datagram", (VALUE(*)(...))t_send_datagram, 5);
rb_define_module_function (EmModule, "close_connection", (VALUE(*)(...))t_close_connection, 2);
rb_define_module_function (EmModule, "report_connection_error_status", (VALUE(*)(...))t_report_connection_error_status, 1);
rb_define_module_function (EmModule, "connect_server", (VALUE(*)(...))t_connect_server, 2);
+ rb_define_module_function (EmModule, "bind_connect_server", (VALUE(*)(...))t_bind_connect_server, 4);
rb_define_module_function (EmModule, "connect_unix_server", (VALUE(*)(...))t_connect_unix_server, 1);
rb_define_module_function (EmModule, "attach_fd", (VALUE (*)(...))t_attach_fd, 3);
rb_define_module_function (EmModule, "detach_fd", (VALUE (*)(...))t_detach_fd, 1);
+ rb_define_module_function (EmModule, "start_proxy", (VALUE (*)(...))t_start_proxy, 2);
+ rb_define_module_function (EmModule, "stop_proxy", (VALUE (*)(...))t_stop_proxy, 1);
+
+ rb_define_module_function (EmModule, "watch_filename", (VALUE (*)(...))t_watch_filename, 1);
+ rb_define_module_function (EmModule, "unwatch_filename", (VALUE (*)(...))t_unwatch_filename, 1);
+
+ rb_define_module_function (EmModule, "watch_pid", (VALUE (*)(...))t_watch_pid, 1);
+ rb_define_module_function (EmModule, "unwatch_pid", (VALUE (*)(...))t_unwatch_pid, 1);
+
rb_define_module_function (EmModule, "current_time", (VALUE(*)(...))t_get_loop_time, 0);
rb_define_module_function (EmModule, "open_udp_socket", (VALUE(*)(...))t_open_udp_socket, 2);
rb_define_module_function (EmModule, "read_keyboard", (VALUE(*)(...))t_read_keyboard, 0);
rb_define_module_function (EmModule, "release_machine", (VALUE(*)(...))t_release_machine, 0);
@@ -806,10 +1001,12 @@
rb_define_module_function (EmModule, "get_max_timer_count", (VALUE(*)(...))t_get_max_timer_count, 0);
rb_define_module_function (EmModule, "set_max_timer_count", (VALUE(*)(...))t_set_max_timer_count, 1);
rb_define_module_function (EmModule, "setuid_string", (VALUE(*)(...))t_setuid_string, 1);
rb_define_module_function (EmModule, "invoke_popen", (VALUE(*)(...))t_invoke_popen, 1);
rb_define_module_function (EmModule, "send_file_data", (VALUE(*)(...))t_send_file_data, 2);
+ rb_define_module_function (EmModule, "get_heartbeat_interval", (VALUE(*)(...))t_get_heartbeat_interval, 0);
+ rb_define_module_function (EmModule, "set_heartbeat_interval", (VALUE(*)(...))t_set_heartbeat_interval, 1);
// Provisional:
rb_define_module_function (EmModule, "_write_file", (VALUE(*)(...))t__write_file, 1);
rb_define_module_function (EmModule, "get_peername", (VALUE(*)(...))t_get_peername, 1);
@@ -819,15 +1016,18 @@
rb_define_module_function (EmModule, "get_comm_inactivity_timeout", (VALUE(*)(...))t_get_comm_inactivity_timeout, 1);
rb_define_module_function (EmModule, "set_comm_inactivity_timeout", (VALUE(*)(...))t_set_comm_inactivity_timeout, 2);
rb_define_module_function (EmModule, "set_rlimit_nofile", (VALUE(*)(...))t_set_rlimit_nofile, 1);
rb_define_module_function (EmModule, "get_connection_count", (VALUE(*)(...))t_get_connection_count, 0);
- // Temporary:
rb_define_module_function (EmModule, "epoll", (VALUE(*)(...))t__epoll, 0);
- rb_define_module_function (EmModule, "kqueue", (VALUE(*)(...))t__kqueue, 0);
-
+ rb_define_module_function (EmModule, "epoll=", (VALUE(*)(...))t__epoll_set, 1);
rb_define_module_function (EmModule, "epoll?", (VALUE(*)(...))t__epoll_p, 0);
+
+ rb_define_module_function (EmModule, "kqueue", (VALUE(*)(...))t__kqueue, 0);
+ rb_define_module_function (EmModule, "kqueue=", (VALUE(*)(...))t__kqueue_set, 1);
rb_define_module_function (EmModule, "kqueue?", (VALUE(*)(...))t__kqueue_p, 0);
+
+ rb_define_module_function (EmModule, "ssl?", (VALUE(*)(...))t__ssl_p, 0);
rb_define_method (EmConnection, "get_outbound_data_size", (VALUE(*)(...))conn_get_outbound_data_size, 0);
rb_define_method (EmConnection, "associate_callback_target", (VALUE(*)(...))conn_associate_callback_target, 1);
rb_define_const (EmModule, "TimerFired", INT2NUM(100));