Project

General

Profile

Bug #595 ยป ensure_fiber.patch

wanabe (_ wanabe), 01/13/2010 06:45 PM

View differences:

cont.c (working copy)
589 589
      case 0:
590 590
	return Qnil;
591 591
      case 1:
592
      case -2:
592 593
	return argv[0];
593 594
      default:
594 595
	return rb_ary_new4(argc, argv);
......
919 920
	/* restored */
920 921
	GetFiberPtr(th->fiber, fib);
921 922
	if (fib->cont.argc == -1) rb_exc_raise(fib->cont.value);
923
	else if (fib->cont.argc == -2) rb_throw_obj(fib->cont.value, Qnil);
922 924
	return fib->cont.value;
923 925
    }
924 926
    else {
......
1013 1015
    return fib->status != TERMINATED ? Qtrue : Qfalse;
1014 1016
}
1015 1017

  
1018
static VALUE
1019
terminate_all_i(VALUE tag, VALUE fibval)
1020
{
1021
   if (rb_fiber_alive_p(fibval)) {
1022
	return fiber_switch(fibval, -2, &tag, 0);
1023
    }
1024
}
1025

  
1026
void
1027
rb_fiber_terminate_all(rb_thread_t *th)
1028
{
1029
    VALUE fibval, tag = rb_newobj();
1030
    rb_fiber_t *fib, *root_fib;
1031
    rb_thread_t *_th = GET_THREAD();
1032

  
1033
    rb_thread_set_current(th);
1034
    fibval = th->root_fiber;
1035
    if (!RTEST(fibval)) return;
1036
    GetFiberPtr(fibval, root_fib);
1037

  
1038
    fib = root_fib->prev_fiber;
1039
    while (fib != root_fib) {
1040
	rb_catch_obj(tag, terminate_all_i, fib->cont.self);
1041
	fib = fib->prev_fiber;
1042
    }
1043
    rb_thread_set_current(_th);
1044
}
1045

  
1016 1046
/*
1017 1047
 *  call-seq:
1018 1048
 *     fiber.resume(args, ...) -> obj
thread.c (working copy)
324 324

  
325 325
static void rb_mutex_unlock_all(mutex_t *mutex, rb_thread_t *th);
326 326
static void rb_mutex_abandon_all(mutex_t *mutexes);
327
void rb_fiber_terminate_all(rb_thread_t *th);
327 328

  
328 329
void
329 330
rb_thread_terminate_all(void)
......
345 346

  
346 347
    thread_debug("rb_thread_terminate_all (main thread: %p)\n", (void *)th);
347 348
    st_foreach(vm->living_threads, terminate_i, (st_data_t)th);
349
    rb_fiber_terminate_all(th);
348 350

  
349 351
    while (!rb_thread_alone()) {
350 352
	PUSH_TAG();
......
1254 1256
	    thread_debug("rb_thread_execute_interrupts: %ld\n", err);
1255 1257

  
1256 1258
	    if (err == eKillSignal || err == eTerminateSignal) {
1259
		rb_fiber_terminate_all(th);
1257 1260
		th->errinfo = INT2FIX(TAG_FATAL);
1258 1261
		TH_JUMP_TAG(th, TAG_FATAL);
1259 1262
	    }