static inline void event_callback (struct em_event* e) { const unsigned long signature = e->signature; int event = e->event; const char *data_str = e->data_str; const unsigned long data_num = e->data_num; switch (event) { case EM_CONNECTION_READ: { VALUE conn = rb_hash_aref (EmConnsHash, ULONG2NUM (signature)); if (conn == Qnil) rb_raise (EM_eConnectionNotBound, "received %lu bytes of data for unknown signature: %lu", data_num, signature); rb_funcall (conn, Intern_receive_data, 1, rb_str_new (data_str, data_num)); return; } case EM_CONNECTION_ACCEPTED: { rb_funcall (EmModule, Intern_event_callback, 3, ULONG2NUM(signature), INT2FIX(event), ULONG2NUM(data_num)); return; } case EM_CONNECTION_UNBOUND: { rb_funcall (EmModule, Intern_event_callback, 3, ULONG2NUM(signature), INT2FIX(event), ULONG2NUM(data_num)); return; } case EM_CONNECTION_COMPLETED: { VALUE conn = ensure_conn(signature); rb_funcall (conn, Intern_connection_completed, 0); return; } case EM_CONNECTION_NOTIFY_READABLE: { VALUE conn = ensure_conn(signature); rb_funcall (conn, Intern_notify_readable, 0); return; } case EM_CONNECTION_NOTIFY_WRITABLE: { VALUE conn = ensure_conn(signature); rb_funcall (conn, Intern_notify_writable, 0); return; } case EM_LOOPBREAK_SIGNAL: { rb_funcall (EmModule, Intern_run_deferred_callbacks, 0); return; } case EM_TIMER_FIRED: { VALUE timer = rb_funcall (EmTimersHash, Intern_delete, 1, ULONG2NUM (data_num)); if (timer == Qnil) { rb_raise (EM_eUnknownTimerFired, "no such timer: %lu", data_num); } else if (timer == Qfalse) { /* Timer Canceled */ } else { rb_funcall (timer, Intern_call, 0); } return; } #ifdef WITH_SSL case EM_SSL_HANDSHAKE_COMPLETED: { VALUE conn = ensure_conn(signature); rb_funcall (conn, Intern_ssl_handshake_completed, 0); return; } case EM_SSL_VERIFY: { VALUE conn = ensure_conn(signature); VALUE should_accept = rb_funcall (conn, Intern_ssl_verify_peer, 1, rb_str_new(data_str, data_num)); if (RTEST(should_accept)) evma_accept_ssl_peer (signature); return; } #endif case EM_PROXY_TARGET_UNBOUND: { VALUE conn = ensure_conn(signature); rb_funcall (conn, Intern_proxy_target_unbound, 0); return; } case EM_PROXY_COMPLETED: { VALUE conn = ensure_conn(signature); rb_funcall (conn, Intern_proxy_completed, 0); return; } } }
static void event_callback (struct em_event* e) { const unsigned long a1 = e->a1; int a2 = e->a2; const char *a3 = e->a3; const unsigned long a4 = e->a4; if (a2 == EM_CONNECTION_READ) { VALUE t = rb_ivar_get (EmModule, Intern_at_conns); VALUE q = rb_hash_aref (t, ULONG2NUM (a1)); if (q == Qnil) rb_raise (EM_eConnectionNotBound, "received %d bytes of data for unknown signature: %lu", a4, a1); rb_funcall (q, Intern_receive_data, 1, rb_str_new (a3, a4)); } else if (a2 == EM_CONNECTION_NOTIFY_READABLE) { VALUE t = rb_ivar_get (EmModule, Intern_at_conns); VALUE q = rb_hash_aref (t, ULONG2NUM (a1)); if (q == Qnil) rb_raise (EM_eConnectionNotBound, "unknown connection: %lu", a1); rb_funcall (q, Intern_notify_readable, 0); } else if (a2 == EM_CONNECTION_NOTIFY_WRITABLE) { VALUE t = rb_ivar_get (EmModule, Intern_at_conns); VALUE q = rb_hash_aref (t, ULONG2NUM (a1)); if (q == Qnil) rb_raise (EM_eConnectionNotBound, "unknown connection: %lu", a1); rb_funcall (q, Intern_notify_writable, 0); } else if (a2 == EM_LOOPBREAK_SIGNAL) { 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, ULONG2NUM (a4)); if (q == Qnil) { rb_raise (EM_eUnknownTimerFired, "no such timer: %lu", a4); } 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, ULONG2NUM (a1)); if (q == Qnil) rb_raise (EM_eConnectionNotBound, "unknown connection: %lu", 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, ULONG2NUM (a1)); if (q == Qnil) rb_raise (EM_eConnectionNotBound, "unknown connection: %lu", 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, ULONG2NUM (a1)); if (q == Qnil) rb_raise (EM_eConnectionNotBound, "unknown connection: %lu", a1); rb_funcall (q, Intern_proxy_target_unbound, 0); } else rb_funcall (EmModule, Intern_event_callback, 3, ULONG2NUM(a1), INT2FIX(a2), a3 ? rb_str_new(a3,a4) : ULONG2NUM(a4)); }