mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* include/ruby/ruby.h: add a type T_DEFERRED.
* gc.c: fix deferred finalizer system. finalize processes of T_DATA and T_FILE are executed after gc process. And fix to use BUILTIN_TYPE() instead of seeing flag. * thread.c, vm_core.h: add RUBY_VM_SET_FINALIZER_INTERRUPT() and check intterupt_flag at rb_thread_execute_interrupts(). * thread.c (mutex_mark): fix to mark next_mutex. * vm.c (rb_thread_mark): fix to mark keeping_mutexes. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18231 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
c30616378e
commit
60be3dc560
6 changed files with 103 additions and 51 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
||||||
|
Sun Jul 27 14:48:37 2008 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* include/ruby/ruby.h: add a type T_DEFERRED.
|
||||||
|
|
||||||
|
* gc.c: fix deferred finalizer system. finalize processes of
|
||||||
|
T_DATA and T_FILE are executed after gc process.
|
||||||
|
And fix to use BUILTIN_TYPE() instead of seeing flag.
|
||||||
|
|
||||||
|
* thread.c, vm_core.h: add RUBY_VM_SET_FINALIZER_INTERRUPT()
|
||||||
|
and check intterupt_flag at rb_thread_execute_interrupts().
|
||||||
|
|
||||||
|
* thread.c (mutex_mark): fix to mark next_mutex.
|
||||||
|
|
||||||
|
* vm.c (rb_thread_mark): fix to mark keeping_mutexes.
|
||||||
|
|
||||||
Sun Jul 27 09:15:28 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Sun Jul 27 09:15:28 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* dln.h (dln_find_exe, dln_find_file): deprecated, use reentrant
|
* dln.h (dln_find_exe, dln_find_file): deprecated, use reentrant
|
||||||
|
|
99
gc.c
99
gc.c
|
@ -579,7 +579,6 @@ assign_heap_slot(rb_objspace_t *objspace)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
lo = 0;
|
lo = 0;
|
||||||
hi = heaps_used;
|
hi = heaps_used;
|
||||||
while (lo < hi) {
|
while (lo < hi) {
|
||||||
|
@ -1081,7 +1080,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr, int lev)
|
||||||
rb_mark_generic_ivar(ptr);
|
rb_mark_generic_ivar(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (obj->as.basic.flags & T_MASK) {
|
switch (BUILTIN_TYPE(obj)) {
|
||||||
case T_NIL:
|
case T_NIL:
|
||||||
case T_FIXNUM:
|
case T_FIXNUM:
|
||||||
rb_bug("rb_gc_mark() called for broken object");
|
rb_bug("rb_gc_mark() called for broken object");
|
||||||
|
@ -1224,7 +1223,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr, int lev)
|
||||||
}
|
}
|
||||||
|
|
||||||
gc_mark(objspace, obj->as.basic.klass, lev);
|
gc_mark(objspace, obj->as.basic.klass, lev);
|
||||||
switch (obj->as.basic.flags & T_MASK) {
|
switch (BUILTIN_TYPE(obj)) {
|
||||||
case T_ICLASS:
|
case T_ICLASS:
|
||||||
case T_CLASS:
|
case T_CLASS:
|
||||||
case T_MODULE:
|
case T_MODULE:
|
||||||
|
@ -1316,18 +1315,27 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr, int lev)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_UNDEF:
|
case T_DEFERRED:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
rb_bug("rb_gc_mark(): unknown data type 0x%lx(%p) %s",
|
rb_bug("rb_gc_mark(): unknown data type 0x%lx(%p) %s",
|
||||||
obj->as.basic.flags & T_MASK, obj,
|
BUILTIN_TYPE(obj), obj,
|
||||||
is_pointer_to_heap(objspace, obj) ? "corrupted object" : "non object");
|
is_pointer_to_heap(objspace, obj) ? "corrupted object" : "non object");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int obj_free(rb_objspace_t *, VALUE);
|
static int obj_free(rb_objspace_t *, VALUE);
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
add_freelist(rb_objspace_t *objspace, RVALUE *p)
|
||||||
|
{
|
||||||
|
VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
|
||||||
|
p->as.free.flags = 0;
|
||||||
|
p->as.free.next = freelist;
|
||||||
|
freelist = p;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
finalize_list(rb_objspace_t *objspace, RVALUE *p)
|
finalize_list(rb_objspace_t *objspace, RVALUE *p)
|
||||||
{
|
{
|
||||||
|
@ -1335,10 +1343,7 @@ finalize_list(rb_objspace_t *objspace, RVALUE *p)
|
||||||
RVALUE *tmp = p->as.free.next;
|
RVALUE *tmp = p->as.free.next;
|
||||||
run_final(objspace, (VALUE)p);
|
run_final(objspace, (VALUE)p);
|
||||||
if (!FL_TEST(p, FL_SINGLETON)) { /* not freeing page */
|
if (!FL_TEST(p, FL_SINGLETON)) { /* not freeing page */
|
||||||
VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
|
add_freelist(objspace, p);
|
||||||
p->as.free.flags = 0;
|
|
||||||
p->as.free.next = freelist;
|
|
||||||
freelist = p;
|
|
||||||
}
|
}
|
||||||
p = tmp;
|
p = tmp;
|
||||||
}
|
}
|
||||||
|
@ -1388,6 +1393,7 @@ gc_sweep(rb_objspace_t *objspace)
|
||||||
|
|
||||||
do_heap_free = (heaps_used * HEAP_OBJ_LIMIT) * 0.65;
|
do_heap_free = (heaps_used * HEAP_OBJ_LIMIT) * 0.65;
|
||||||
free_min = (heaps_used * HEAP_OBJ_LIMIT) * 0.2;
|
free_min = (heaps_used * HEAP_OBJ_LIMIT) * 0.2;
|
||||||
|
|
||||||
if (free_min < FREE_MIN) {
|
if (free_min < FREE_MIN) {
|
||||||
do_heap_free = heaps_used * HEAP_OBJ_LIMIT;
|
do_heap_free = heaps_used * HEAP_OBJ_LIMIT;
|
||||||
free_min = FREE_MIN;
|
free_min = FREE_MIN;
|
||||||
|
@ -1400,25 +1406,28 @@ gc_sweep(rb_objspace_t *objspace)
|
||||||
int n = 0;
|
int n = 0;
|
||||||
RVALUE *free = freelist;
|
RVALUE *free = freelist;
|
||||||
RVALUE *final = final_list;
|
RVALUE *final = final_list;
|
||||||
|
int deferred;
|
||||||
|
|
||||||
p = heaps[i].slot; pend = p + heaps[i].limit;
|
p = heaps[i].slot; pend = p + heaps[i].limit;
|
||||||
while (p < pend) {
|
while (p < pend) {
|
||||||
if (!(p->as.basic.flags & FL_MARK)) {
|
if (!(p->as.basic.flags & FL_MARK)) {
|
||||||
if (p->as.basic.flags && obj_free(objspace, (VALUE)p) ||
|
if (p->as.basic.flags &&
|
||||||
need_call_final && FL_TEST(p, FL_FINALIZE)) {
|
((deferred = obj_free(objspace, (VALUE)p)) ||
|
||||||
p->as.free.flags |= FL_MARK; /* remain marked */
|
((FL_TEST(p, FL_FINALIZE)) && need_call_final))) {
|
||||||
|
if (!deferred) {
|
||||||
|
p->as.free.flags = T_DEFERRED;
|
||||||
|
RDATA(p)->dfree = 0;
|
||||||
|
}
|
||||||
|
p->as.free.flags |= FL_MARK;
|
||||||
p->as.free.next = final_list;
|
p->as.free.next = final_list;
|
||||||
final_list = p;
|
final_list = p;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
|
add_freelist(objspace, p);
|
||||||
p->as.free.flags = 0;
|
|
||||||
p->as.free.next = freelist;
|
|
||||||
freelist = p;
|
|
||||||
}
|
}
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
else if (RBASIC(p)->flags == FL_MARK) {
|
else if (BUILTIN_TYPE(p) == T_DEFERRED) {
|
||||||
/* objects to be finalized */
|
/* objects to be finalized */
|
||||||
/* do nothing remain marked */
|
/* do nothing remain marked */
|
||||||
}
|
}
|
||||||
|
@ -1455,25 +1464,24 @@ gc_sweep(rb_objspace_t *objspace)
|
||||||
/* clear finalization list */
|
/* clear finalization list */
|
||||||
if (final_list) {
|
if (final_list) {
|
||||||
deferred_final_list = final_list;
|
deferred_final_list = final_list;
|
||||||
return;
|
RUBY_VM_SET_FINALIZER_INTERRUPT(GET_THREAD());
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
free_unused_heaps(objspace);
|
free_unused_heaps(objspace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_gc_force_recycle(VALUE p)
|
rb_gc_force_recycle(VALUE p)
|
||||||
{
|
{
|
||||||
rb_objspace_t *objspace = &rb_objspace;
|
rb_objspace_t *objspace = &rb_objspace;
|
||||||
VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
|
add_freelist(objspace, (RVALUE *)p);
|
||||||
RANY(p)->as.free.flags = 0;
|
|
||||||
RANY(p)->as.free.next = freelist;
|
|
||||||
freelist = RANY(p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
obj_free(rb_objspace_t *objspace, VALUE obj)
|
obj_free(rb_objspace_t *objspace, VALUE obj)
|
||||||
{
|
{
|
||||||
switch (RANY(obj)->as.basic.flags & T_MASK) {
|
switch (BUILTIN_TYPE(obj)) {
|
||||||
case T_NIL:
|
case T_NIL:
|
||||||
case T_FIXNUM:
|
case T_FIXNUM:
|
||||||
case T_TRUE:
|
case T_TRUE:
|
||||||
|
@ -1486,7 +1494,7 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
|
||||||
rb_free_generic_ivar((VALUE)obj);
|
rb_free_generic_ivar((VALUE)obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (RANY(obj)->as.basic.flags & T_MASK) {
|
switch (BUILTIN_TYPE(obj)) {
|
||||||
case T_OBJECT:
|
case T_OBJECT:
|
||||||
if (!(RANY(obj)->as.basic.flags & ROBJECT_EMBED) &&
|
if (!(RANY(obj)->as.basic.flags & ROBJECT_EMBED) &&
|
||||||
RANY(obj)->as.object.as.heap.ivptr) {
|
RANY(obj)->as.object.as.heap.ivptr) {
|
||||||
|
@ -1527,10 +1535,15 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
|
||||||
xfree(DATA_PTR(obj));
|
xfree(DATA_PTR(obj));
|
||||||
}
|
}
|
||||||
else if (RANY(obj)->as.data.dfree) {
|
else if (RANY(obj)->as.data.dfree) {
|
||||||
|
if (1) {
|
||||||
RANY(obj)->as.basic.flags &= ~T_MASK;
|
RANY(obj)->as.basic.flags &= ~T_MASK;
|
||||||
RANY(obj)->as.basic.flags |= T_UNDEF;
|
RANY(obj)->as.basic.flags |= T_DEFERRED;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
(*RANY(obj)->as.data.dfree)(DATA_PTR(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case T_MATCH:
|
case T_MATCH:
|
||||||
|
@ -1545,12 +1558,17 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
|
||||||
case T_FILE:
|
case T_FILE:
|
||||||
if (RANY(obj)->as.file.fptr) {
|
if (RANY(obj)->as.file.fptr) {
|
||||||
rb_io_t *fptr = RANY(obj)->as.file.fptr;
|
rb_io_t *fptr = RANY(obj)->as.file.fptr;
|
||||||
|
if (1) {
|
||||||
RANY(obj)->as.basic.flags &= ~T_MASK;
|
RANY(obj)->as.basic.flags &= ~T_MASK;
|
||||||
RANY(obj)->as.basic.flags |= T_UNDEF;
|
RANY(obj)->as.basic.flags |= T_DEFERRED;
|
||||||
RDATA(obj)->dfree = (void (*)(void*))rb_io_fptr_finalize;
|
RDATA(obj)->dfree = (void (*)(void*))rb_io_fptr_finalize;
|
||||||
RDATA(obj)->data = fptr;
|
RDATA(obj)->data = fptr;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
rb_io_fptr_finalize(fptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case T_RATIONAL:
|
case T_RATIONAL:
|
||||||
case T_COMPLEX:
|
case T_COMPLEX:
|
||||||
|
@ -1587,14 +1605,14 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_UNDEF:
|
case T_DEFERRED:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
rb_bug("gc_sweep(): unknown data type 0x%lx(%p)",
|
rb_bug("gc_sweep(): unknown data type 0x%lx(%p)",
|
||||||
RANY(obj)->as.basic.flags & T_MASK, (void*)obj);
|
BUILTIN_TYPE(obj), (void*)obj);
|
||||||
}
|
}
|
||||||
RANY(obj)->as.basic.flags &= ~T_MASK;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1867,7 +1885,7 @@ os_obj_of(rb_objspace_t *objspace, VALUE of)
|
||||||
case T_NONE:
|
case T_NONE:
|
||||||
case T_ICLASS:
|
case T_ICLASS:
|
||||||
case T_NODE:
|
case T_NODE:
|
||||||
case T_UNDEF:
|
case T_DEFERRED:
|
||||||
continue;
|
continue;
|
||||||
case T_CLASS:
|
case T_CLASS:
|
||||||
if (FL_TEST(p, FL_SINGLETON)) continue;
|
if (FL_TEST(p, FL_SINGLETON)) continue;
|
||||||
|
@ -2018,17 +2036,19 @@ static void
|
||||||
run_final(rb_objspace_t *objspace, VALUE obj)
|
run_final(rb_objspace_t *objspace, VALUE obj)
|
||||||
{
|
{
|
||||||
long i;
|
long i;
|
||||||
int status, critical_save = rb_thread_critical;
|
int status;
|
||||||
VALUE args[3], table, objid;
|
VALUE args[3], table, objid;
|
||||||
|
|
||||||
objid = rb_obj_id(obj); /* make obj into id */
|
objid = rb_obj_id(obj); /* make obj into id */
|
||||||
rb_thread_critical = Qtrue;
|
|
||||||
if ((RANY(obj)->as.basic.flags & T_MASK) == T_UNDEF) {
|
if (RDATA(obj)->dfree) {
|
||||||
(*RANY(obj)->as.data.dfree)(DATA_PTR(obj));
|
(*RDATA(obj)->dfree)(DATA_PTR(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (finalizer_table &&
|
||||||
|
st_delete(finalizer_table, (st_data_t*)&obj, &table)) {
|
||||||
args[1] = 0;
|
args[1] = 0;
|
||||||
args[2] = (VALUE)rb_safe_level();
|
args[2] = (VALUE)rb_safe_level();
|
||||||
if (finalizer_table && st_delete(finalizer_table, (st_data_t*)&obj, &table)) {
|
|
||||||
if (!args[1] && RARRAY_LEN(table) > 0) {
|
if (!args[1] && RARRAY_LEN(table) > 0) {
|
||||||
args[1] = rb_obj_freeze(rb_ary_new3(1, objid));
|
args[1] = rb_obj_freeze(rb_ary_new3(1, objid));
|
||||||
}
|
}
|
||||||
|
@ -2039,15 +2059,14 @@ run_final(rb_objspace_t *objspace, VALUE obj)
|
||||||
rb_protect(run_single_final, (VALUE)args, &status);
|
rb_protect(run_single_final, (VALUE)args, &status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rb_thread_critical = critical_save;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gc_finalize_deferred(rb_objspace_t *objspace)
|
gc_finalize_deferred(rb_objspace_t *objspace)
|
||||||
{
|
{
|
||||||
RVALUE *p = deferred_final_list;
|
RVALUE *p = deferred_final_list;
|
||||||
|
|
||||||
deferred_final_list = 0;
|
deferred_final_list = 0;
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
finalize_list(objspace, p);
|
finalize_list(objspace, p);
|
||||||
}
|
}
|
||||||
|
@ -2065,7 +2084,10 @@ chain_finalized_object(st_data_t key, st_data_t val, st_data_t arg)
|
||||||
{
|
{
|
||||||
RVALUE *p = (RVALUE *)key, **final_list = (RVALUE **)arg;
|
RVALUE *p = (RVALUE *)key, **final_list = (RVALUE **)arg;
|
||||||
if (p->as.basic.flags & FL_FINALIZE) {
|
if (p->as.basic.flags & FL_FINALIZE) {
|
||||||
p->as.free.flags = FL_MARK; /* remain marked */
|
if (BUILTIN_TYPE(p) != T_DEFERRED) {
|
||||||
|
p->as.free.flags = FL_MARK | T_DEFERRED; /* remain marked */
|
||||||
|
RDATA(p)->dfree = 0;
|
||||||
|
}
|
||||||
p->as.free.next = *final_list;
|
p->as.free.next = *final_list;
|
||||||
*final_list = p;
|
*final_list = p;
|
||||||
}
|
}
|
||||||
|
@ -2345,6 +2367,7 @@ count_objects(int argc, VALUE *argv, VALUE os)
|
||||||
COUNT_TYPE(T_UNDEF);
|
COUNT_TYPE(T_UNDEF);
|
||||||
COUNT_TYPE(T_NODE);
|
COUNT_TYPE(T_NODE);
|
||||||
COUNT_TYPE(T_ICLASS);
|
COUNT_TYPE(T_ICLASS);
|
||||||
|
COUNT_TYPE(T_DEFERRED);
|
||||||
#undef COUNT_TYPE
|
#undef COUNT_TYPE
|
||||||
default: type = INT2NUM(i); break;
|
default: type = INT2NUM(i); break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,6 +302,7 @@ enum ruby_value_type {
|
||||||
RUBY_T_UNDEF = 0x1b,
|
RUBY_T_UNDEF = 0x1b,
|
||||||
RUBY_T_NODE = 0x1c,
|
RUBY_T_NODE = 0x1c,
|
||||||
RUBY_T_ICLASS = 0x1d,
|
RUBY_T_ICLASS = 0x1d,
|
||||||
|
RUBY_T_DEFERRED = 0x1e,
|
||||||
|
|
||||||
RUBY_T_MASK = 0x1f
|
RUBY_T_MASK = 0x1f
|
||||||
};
|
};
|
||||||
|
@ -330,6 +331,7 @@ enum ruby_value_type {
|
||||||
#define T_COMPLEX RUBY_T_COMPLEX
|
#define T_COMPLEX RUBY_T_COMPLEX
|
||||||
#define T_UNDEF RUBY_T_UNDEF
|
#define T_UNDEF RUBY_T_UNDEF
|
||||||
#define T_NODE RUBY_T_NODE
|
#define T_NODE RUBY_T_NODE
|
||||||
|
#define T_DEFERRED RUBY_T_DEFERRED
|
||||||
#define T_MASK RUBY_T_MASK
|
#define T_MASK RUBY_T_MASK
|
||||||
|
|
||||||
#define BUILTIN_TYPE(x) (((struct RBasic*)(x))->flags & T_MASK)
|
#define BUILTIN_TYPE(x) (((struct RBasic*)(x))->flags & T_MASK)
|
||||||
|
|
14
thread.c
14
thread.c
|
@ -935,8 +935,12 @@ void
|
||||||
rb_thread_execute_interrupts(rb_thread_t *th)
|
rb_thread_execute_interrupts(rb_thread_t *th)
|
||||||
{
|
{
|
||||||
if (th->raised_flag) return;
|
if (th->raised_flag) return;
|
||||||
|
|
||||||
while (th->interrupt_flag) {
|
while (th->interrupt_flag) {
|
||||||
enum rb_thread_status status = th->status;
|
enum rb_thread_status status = th->status;
|
||||||
|
int timer_interrupt = th->interrupt_flag & 0x01;
|
||||||
|
int finalizer_interrupt = th->interrupt_flag & 0x04;
|
||||||
|
|
||||||
th->status = THREAD_RUNNABLE;
|
th->status = THREAD_RUNNABLE;
|
||||||
th->interrupt_flag = 0;
|
th->interrupt_flag = 0;
|
||||||
|
|
||||||
|
@ -963,10 +967,15 @@ rb_thread_execute_interrupts(rb_thread_t *th)
|
||||||
}
|
}
|
||||||
th->status = status;
|
th->status = status;
|
||||||
|
|
||||||
/* thread pass */
|
if (finalizer_interrupt) {
|
||||||
|
rb_gc_finalize_deferred();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timer_interrupt) {
|
||||||
|
EXEC_EVENT_HOOK(th, RUBY_EVENT_SWITCH, th->cfp->self, 0, 0);
|
||||||
rb_thread_schedule();
|
rb_thread_schedule();
|
||||||
}
|
}
|
||||||
EXEC_EVENT_HOOK(th, RUBY_EVENT_SWITCH, th->cfp->self, 0, 0);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2494,6 +2503,7 @@ mutex_mark(void *ptr)
|
||||||
{
|
{
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
mutex_t *mutex = ptr;
|
mutex_t *mutex = ptr;
|
||||||
|
rb_gc_mark(mutex->next_mutex);
|
||||||
if (mutex->th) {
|
if (mutex->th) {
|
||||||
rb_gc_mark(mutex->th->self);
|
rb_gc_mark(mutex->th->self);
|
||||||
}
|
}
|
||||||
|
|
1
vm.c
1
vm.c
|
@ -1551,6 +1551,7 @@ rb_thread_mark(void *ptr)
|
||||||
RUBY_MARK_UNLESS_NULL(th->last_status);
|
RUBY_MARK_UNLESS_NULL(th->last_status);
|
||||||
|
|
||||||
RUBY_MARK_UNLESS_NULL(th->locking_mutex);
|
RUBY_MARK_UNLESS_NULL(th->locking_mutex);
|
||||||
|
RUBY_MARK_UNLESS_NULL(th->keeping_mutexes);
|
||||||
|
|
||||||
rb_mark_tbl(th->local_storage);
|
rb_mark_tbl(th->local_storage);
|
||||||
|
|
||||||
|
|
|
@ -690,12 +690,13 @@ extern rb_vm_t *ruby_current_vm;
|
||||||
|
|
||||||
#define RUBY_VM_SET_INTERRUPT(th) ((th)->interrupt_flag |= 0x02)
|
#define RUBY_VM_SET_INTERRUPT(th) ((th)->interrupt_flag |= 0x02)
|
||||||
#define RUBY_VM_SET_TIMER_INTERRUPT(th) ((th)->interrupt_flag |= 0x01)
|
#define RUBY_VM_SET_TIMER_INTERRUPT(th) ((th)->interrupt_flag |= 0x01)
|
||||||
|
#define RUBY_VM_SET_FINALIZER_INTERRUPT(th) ((th)->interrupt_flag |= 0x04)
|
||||||
#define RUBY_VM_INTERRUPTED(th) ((th)->interrupt_flag & 0x02)
|
#define RUBY_VM_INTERRUPTED(th) ((th)->interrupt_flag & 0x02)
|
||||||
|
|
||||||
void rb_thread_execute_interrupts(rb_thread_t *);
|
void rb_thread_execute_interrupts(rb_thread_t *);
|
||||||
|
|
||||||
#define RUBY_VM_CHECK_INTS_TH(th) do { \
|
#define RUBY_VM_CHECK_INTS_TH(th) do { \
|
||||||
if(th->interrupt_flag){ \
|
if (th->interrupt_flag) { \
|
||||||
/* TODO: trap something event */ \
|
/* TODO: trap something event */ \
|
||||||
rb_thread_execute_interrupts(th); \
|
rb_thread_execute_interrupts(th); \
|
||||||
} \
|
} \
|
||||||
|
|
Loading…
Reference in a new issue