extern "C" VALUE rb_rescue(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*r_proc)(ANYARGS), VALUE data2) { try { return (*b_proc)(data1); } catch (jruby::JavaException& ex) { JLocalEnv env; jthrowable t = ex.getCause(env); if (!env->IsInstanceOf(t, RaiseException_class)) { // Not a ruby exception, just propagate throw; } jobject rubyException = env->GetObjectField(t, RaiseException_exception_field); checkExceptions(env); VALUE exc = objectToValue(env, rubyException); if (rb_obj_is_kind_of(exc, rb_eStandardError)) { VALUE result = (*r_proc)(data2); env->CallStaticVoidMethod(JRuby_class, JRuby_clearErrorInfo, jruby::getRuntime()); return result; } rb_raise(rb_eTypeError, "wrong exception type raised (expected StandardError subclass)"); return Qnil; } }
extern "C" VALUE rb_rescue2(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*r_proc)(ANYARGS), VALUE data2, ...) { try { return (*b_proc)(data1); } catch (jruby::JavaException& ex) { JLocalEnv env; jthrowable t = ex.getCause(env); if (!env->IsInstanceOf(t, RaiseException_class)) { // Not a ruby exception, just propagate throw; } jobject rubyException = env->GetObjectField(t, RaiseException_exception_field); checkExceptions(env); VALUE exc = objectToValue(env, rubyException); va_list ap; va_start(ap, data2); VALUE eclass = 0; bool handle = false; while ((eclass = va_arg(ap, VALUE)) != 0) { if (rb_obj_is_kind_of(exc, eclass)) { handle = true; break; } } va_end(ap); if (handle) { VALUE result = (*r_proc)(data2); env->CallStaticVoidMethod(JRuby_class, JRuby_clearErrorInfo, jruby::getRuntime()); return result; } rb_raise(rb_eTypeError, "wrong exception type raised"); return Qnil; } }
extern "C" int rb_thread_select(int max, fd_set * read, fd_set * write, fd_set * except, struct timeval *timeout) { JLocalEnv env; if (!read && !write && !except) { // Just sleep for the specified amount of time long interval = timeout ? (timeout->tv_sec * 1000 + timeout->tv_usec / 1000) : 0; env->CallStaticVoidMethod(JRuby_class, JRuby_threadSleep, getRuntime(), (jint)interval); checkExceptions(env); return 0; } else { void** data = (void**)xmalloc(sizeof(void*) * 5); data[0] = (void*)max; data[1] = (void*)read; data[2] = (void*)write; data[3] = (void*)except; data[4] = (void*)timeout; VALUE ret = rb_thread_blocking_region(jruby_select, (void*)data, NULL, NULL); return (int)ret; } }