mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
thread.c: reuse tag
* thread.c (rb_thread_terminate_all): reuse the tag pushed before a loop, instead of pushing/popping same tag repeatedly. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51301 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
1b8ff4f799
commit
d8d9148506
1 changed files with 20 additions and 17 deletions
37
thread.c
37
thread.c
|
@ -179,6 +179,12 @@ vm_check_ints_blocking(rb_thread_t *th)
|
||||||
rb_threadptr_execute_interrupts(th, 1);
|
rb_threadptr_execute_interrupts(th, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
vm_living_thread_num(rb_vm_t *vm)
|
||||||
|
{
|
||||||
|
return (int)vm->living_thread_num;
|
||||||
|
}
|
||||||
|
|
||||||
#if THREAD_DEBUG
|
#if THREAD_DEBUG
|
||||||
#ifdef HAVE_VA_ARGS_MACRO
|
#ifdef HAVE_VA_ARGS_MACRO
|
||||||
void rb_thread_debug(const char *file, int line, const char *fmt, ...);
|
void rb_thread_debug(const char *file, int line, const char *fmt, ...);
|
||||||
|
@ -479,6 +485,7 @@ rb_thread_terminate_all(void)
|
||||||
{
|
{
|
||||||
rb_thread_t *th = GET_THREAD(); /* main thread */
|
rb_thread_t *th = GET_THREAD(); /* main thread */
|
||||||
rb_vm_t *vm = th->vm;
|
rb_vm_t *vm = th->vm;
|
||||||
|
volatile int sleeping = 0;
|
||||||
|
|
||||||
if (vm->main_thread != th) {
|
if (vm->main_thread != th) {
|
||||||
rb_bug("rb_thread_terminate_all: called by child thread (%p, %p)",
|
rb_bug("rb_thread_terminate_all: called by child thread (%p, %p)",
|
||||||
|
@ -488,33 +495,35 @@ rb_thread_terminate_all(void)
|
||||||
/* unlock all locking mutexes */
|
/* unlock all locking mutexes */
|
||||||
rb_threadptr_unlock_all_locking_mutexes(th);
|
rb_threadptr_unlock_all_locking_mutexes(th);
|
||||||
|
|
||||||
retry:
|
TH_PUSH_TAG(th);
|
||||||
thread_debug("rb_thread_terminate_all (main thread: %p)\n", (void *)th);
|
if (TH_EXEC_TAG() == 0) {
|
||||||
terminate_all(vm, th);
|
retry:
|
||||||
|
thread_debug("rb_thread_terminate_all (main thread: %p)\n", (void *)th);
|
||||||
|
terminate_all(vm, th);
|
||||||
|
|
||||||
while (!rb_thread_alone()) {
|
while (vm_living_thread_num(vm) > 1) {
|
||||||
int state;
|
|
||||||
|
|
||||||
TH_PUSH_TAG(th);
|
|
||||||
if ((state = TH_EXEC_TAG()) == 0) {
|
|
||||||
/*
|
/*
|
||||||
* Thread exiting routine in thread_start_func_2 notify
|
* Thread exiting routine in thread_start_func_2 notify
|
||||||
* me when the last sub-thread exit.
|
* me when the last sub-thread exit.
|
||||||
*/
|
*/
|
||||||
|
sleeping = 1;
|
||||||
native_sleep(th, 0);
|
native_sleep(th, 0);
|
||||||
RUBY_VM_CHECK_INTS_BLOCKING(th);
|
RUBY_VM_CHECK_INTS_BLOCKING(th);
|
||||||
|
sleeping = 0;
|
||||||
}
|
}
|
||||||
TH_POP_TAG();
|
}
|
||||||
|
else {
|
||||||
/*
|
/*
|
||||||
* When caught an exception (e.g. Ctrl+C), let's broadcast
|
* When caught an exception (e.g. Ctrl+C), let's broadcast
|
||||||
* kill request again to ensure killing all threads even
|
* kill request again to ensure killing all threads even
|
||||||
* if they are blocked on sleep, mutex, etc.
|
* if they are blocked on sleep, mutex, etc.
|
||||||
*/
|
*/
|
||||||
if (state) {
|
if (sleeping) {
|
||||||
|
sleeping = 0;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
TH_POP_TAG();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -3054,12 +3063,6 @@ thread_keys_i(ID key, VALUE value, VALUE ary)
|
||||||
return ST_CONTINUE;
|
return ST_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
vm_living_thread_num(rb_vm_t *vm)
|
|
||||||
{
|
|
||||||
return (int)vm->living_thread_num;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
rb_thread_alone(void)
|
rb_thread_alone(void)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue