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;
    }
    }
}
예제 #2
0
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));
}