* vm_core.h, thread.c: It is now prohibited to use Data_Get_Struct in
*_free against an object that is going to be free'ed. So, change type of thread_t#keeping_mutexes from VALUE to mutex_t. * vm.c: remove mark to keeping_mutexes. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18235 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
787cde7f9a
commit
d76ab40bea
@ -1,3 +1,11 @@
|
|||||||
|
Mon Jul 28 00:18:47 2008 Yusuke Endoh <mame@tsg.ne.jp>
|
||||||
|
|
||||||
|
* vm_core.h, thread.c: It is now prohibited to use Data_Get_Struct in
|
||||||
|
*_free against an object that is going to be free'ed. So, change type
|
||||||
|
of thread_t#keeping_mutexes from VALUE to mutex_t.
|
||||||
|
|
||||||
|
* vm.c: remove mark to keeping_mutexes.
|
||||||
|
|
||||||
Sun Jul 27 23:32:42 2008 Yusuke Endoh <mame@tsg.ne.jp>
|
Sun Jul 27 23:32:42 2008 Yusuke Endoh <mame@tsg.ne.jp>
|
||||||
|
|
||||||
* test/openssl/test_ssl.rb (server_loop): rescue Errno::EINVAL and
|
* test/openssl/test_ssl.rb (server_loop): rescue Errno::EINVAL and
|
||||||
|
43
thread.c
43
thread.c
@ -62,7 +62,9 @@ static double timeofday(void);
|
|||||||
struct timeval rb_time_interval(VALUE);
|
struct timeval rb_time_interval(VALUE);
|
||||||
static int rb_thread_dead(rb_thread_t *th);
|
static int rb_thread_dead(rb_thread_t *th);
|
||||||
|
|
||||||
static void rb_mutex_unlock_all(VALUE);
|
typedef struct rb_mutex_struct mutex_t;
|
||||||
|
|
||||||
|
static void rb_mutex_unlock_all(mutex_t *mutex);
|
||||||
static void rb_check_deadlock(rb_vm_t *vm);
|
static void rb_check_deadlock(rb_vm_t *vm);
|
||||||
|
|
||||||
void rb_signal_exec(rb_thread_t *th, int sig);
|
void rb_signal_exec(rb_thread_t *th, int sig);
|
||||||
@ -402,7 +404,7 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_s
|
|||||||
/* unlock all locking mutexes */
|
/* unlock all locking mutexes */
|
||||||
if (th->keeping_mutexes) {
|
if (th->keeping_mutexes) {
|
||||||
rb_mutex_unlock_all(th->keeping_mutexes);
|
rb_mutex_unlock_all(th->keeping_mutexes);
|
||||||
th->keeping_mutexes = Qfalse;
|
th->keeping_mutexes = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* delete self from living_threads */
|
/* delete self from living_threads */
|
||||||
@ -2485,31 +2487,11 @@ thgroup_add(VALUE group, VALUE thread)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct mutex_struct {
|
|
||||||
rb_thread_lock_t lock;
|
|
||||||
rb_thread_cond_t cond;
|
|
||||||
rb_thread_t volatile *th;
|
|
||||||
volatile int cond_waiting, cond_notified;
|
|
||||||
VALUE next_mutex;
|
|
||||||
} mutex_t;
|
|
||||||
|
|
||||||
#define GetMutexPtr(obj, tobj) \
|
#define GetMutexPtr(obj, tobj) \
|
||||||
Data_Get_Struct(obj, mutex_t, tobj)
|
Data_Get_Struct(obj, mutex_t, tobj)
|
||||||
|
|
||||||
static const char *mutex_unlock(mutex_t *mutex);
|
static const char *mutex_unlock(mutex_t *mutex);
|
||||||
|
|
||||||
static void
|
|
||||||
mutex_mark(void *ptr)
|
|
||||||
{
|
|
||||||
if (ptr) {
|
|
||||||
mutex_t *mutex = ptr;
|
|
||||||
rb_gc_mark(mutex->next_mutex);
|
|
||||||
if (mutex->th) {
|
|
||||||
rb_gc_mark(mutex->th->self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mutex_free(void *ptr)
|
mutex_free(void *ptr)
|
||||||
{
|
{
|
||||||
@ -2531,7 +2513,7 @@ mutex_alloc(VALUE klass)
|
|||||||
VALUE volatile obj;
|
VALUE volatile obj;
|
||||||
mutex_t *mutex;
|
mutex_t *mutex;
|
||||||
|
|
||||||
obj = Data_Make_Struct(klass, mutex_t, mutex_mark, mutex_free, mutex);
|
obj = Data_Make_Struct(klass, mutex_t, NULL, mutex_free, mutex);
|
||||||
native_mutex_initialize(&mutex->lock);
|
native_mutex_initialize(&mutex->lock);
|
||||||
native_cond_initialize(&mutex->cond);
|
native_cond_initialize(&mutex->cond);
|
||||||
return obj;
|
return obj;
|
||||||
@ -2572,12 +2554,13 @@ rb_mutex_locked_p(VALUE self)
|
|||||||
static void
|
static void
|
||||||
mutex_locked(rb_thread_t *th, VALUE self)
|
mutex_locked(rb_thread_t *th, VALUE self)
|
||||||
{
|
{
|
||||||
|
mutex_t *mutex;
|
||||||
|
GetMutexPtr(self, mutex);
|
||||||
|
|
||||||
if (th->keeping_mutexes) {
|
if (th->keeping_mutexes) {
|
||||||
mutex_t *mutex;
|
|
||||||
GetMutexPtr(self, mutex);
|
|
||||||
mutex->next_mutex = th->keeping_mutexes;
|
mutex->next_mutex = th->keeping_mutexes;
|
||||||
}
|
}
|
||||||
th->keeping_mutexes = self;
|
th->keeping_mutexes = mutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2743,14 +2726,14 @@ mutex_unlock(mutex_t *mutex)
|
|||||||
native_mutex_unlock(&mutex->lock);
|
native_mutex_unlock(&mutex->lock);
|
||||||
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
GetMutexPtr(th->keeping_mutexes, th_mutex);
|
th_mutex = th->keeping_mutexes;
|
||||||
if (th_mutex == mutex) {
|
if (th_mutex == mutex) {
|
||||||
th->keeping_mutexes = mutex->next_mutex;
|
th->keeping_mutexes = mutex->next_mutex;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
while (1) {
|
while (1) {
|
||||||
mutex_t *tmp_mutex;
|
mutex_t *tmp_mutex;
|
||||||
GetMutexPtr(th_mutex->next_mutex, tmp_mutex);
|
tmp_mutex = th_mutex->next_mutex;
|
||||||
if (tmp_mutex == mutex) {
|
if (tmp_mutex == mutex) {
|
||||||
th_mutex->next_mutex = tmp_mutex->next_mutex;
|
th_mutex->next_mutex = tmp_mutex->next_mutex;
|
||||||
break;
|
break;
|
||||||
@ -2785,13 +2768,13 @@ rb_mutex_unlock(VALUE self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rb_mutex_unlock_all(VALUE mutexes)
|
rb_mutex_unlock_all(mutex_t *mutexes)
|
||||||
{
|
{
|
||||||
const char *err;
|
const char *err;
|
||||||
mutex_t *mutex;
|
mutex_t *mutex;
|
||||||
|
|
||||||
while (mutexes) {
|
while (mutexes) {
|
||||||
GetMutexPtr(mutexes, mutex);
|
mutex = mutexes;
|
||||||
/* rb_warn("mutex #<%s:%p> remains to be locked by terminated thread",
|
/* rb_warn("mutex #<%s:%p> remains to be locked by terminated thread",
|
||||||
rb_obj_classname(mutexes), (void*)mutexes); */
|
rb_obj_classname(mutexes), (void*)mutexes); */
|
||||||
mutexes = mutex->next_mutex;
|
mutexes = mutex->next_mutex;
|
||||||
|
3
vm.c
3
vm.c
@ -1478,7 +1478,7 @@ thread_free(void *ptr)
|
|||||||
if (th->locking_mutex != Qfalse) {
|
if (th->locking_mutex != Qfalse) {
|
||||||
rb_bug("thread_free: locking_mutex must be NULL (%p:%ld)", th, th->locking_mutex);
|
rb_bug("thread_free: locking_mutex must be NULL (%p:%ld)", th, th->locking_mutex);
|
||||||
}
|
}
|
||||||
if (th->keeping_mutexes != Qfalse) {
|
if (th->keeping_mutexes != NULL) {
|
||||||
rb_bug("thread_free: keeping_mutexes must be NULL (%p:%ld)", th, th->locking_mutex);
|
rb_bug("thread_free: keeping_mutexes must be NULL (%p:%ld)", th, th->locking_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1551,7 +1551,6 @@ 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);
|
||||||
|
|
||||||
|
13
vm_core.h
13
vm_core.h
@ -396,6 +396,8 @@ struct rb_unblock_callback {
|
|||||||
void *arg;
|
void *arg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct rb_mutex_struct;
|
||||||
|
|
||||||
struct rb_thread_struct
|
struct rb_thread_struct
|
||||||
{
|
{
|
||||||
VALUE self;
|
VALUE self;
|
||||||
@ -443,7 +445,7 @@ struct rb_thread_struct
|
|||||||
rb_thread_lock_t interrupt_lock;
|
rb_thread_lock_t interrupt_lock;
|
||||||
struct rb_unblock_callback unblock;
|
struct rb_unblock_callback unblock;
|
||||||
VALUE locking_mutex;
|
VALUE locking_mutex;
|
||||||
VALUE keeping_mutexes;
|
struct rb_mutex_struct *keeping_mutexes;
|
||||||
int transition_for_lock;
|
int transition_for_lock;
|
||||||
|
|
||||||
struct rb_vm_tag *tag;
|
struct rb_vm_tag *tag;
|
||||||
@ -496,6 +498,15 @@ struct rb_thread_struct
|
|||||||
int abort_on_exception;
|
int abort_on_exception;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct rb_mutex_struct
|
||||||
|
{
|
||||||
|
rb_thread_lock_t lock;
|
||||||
|
rb_thread_cond_t cond;
|
||||||
|
struct rb_thread_struct volatile *th;
|
||||||
|
volatile int cond_waiting, cond_notified;
|
||||||
|
struct rb_mutex_struct *next_mutex;
|
||||||
|
};
|
||||||
|
|
||||||
/* iseq.c */
|
/* iseq.c */
|
||||||
VALUE rb_iseq_new(NODE*, VALUE, VALUE, VALUE, VALUE);
|
VALUE rb_iseq_new(NODE*, VALUE, VALUE, VALUE, VALUE);
|
||||||
VALUE rb_iseq_new_with_bopt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE);
|
VALUE rb_iseq_new_with_bopt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user