summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-07-27 15:20:01 +0000
committermame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-07-27 15:20:01 +0000
commitd76ab40bea1532214e8f22c46da7109b9e4c4766 (patch)
tree67dbd42d733a1685af430b7da550267580e56b86
parent787cde7f9ab12edafe7559f501a8e21d89e72d72 (diff)
* 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
-rw-r--r--ChangeLog8
-rw-r--r--thread.c43
-rw-r--r--vm.c3
-rw-r--r--vm_core.h13
4 files changed, 34 insertions, 33 deletions
diff --git a/ChangeLog b/ChangeLog
index 8aad884d5e..d427307870 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
* test/openssl/test_ssl.rb (server_loop): rescue Errno::EINVAL and
diff --git a/thread.c b/thread.c
index 2279c4491e..0a313abe13 100644
--- a/thread.c
+++ b/thread.c
@@ -62,7 +62,9 @@ static double timeofday(void);
struct timeval rb_time_interval(VALUE);
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);
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 */
if (th->keeping_mutexes) {
rb_mutex_unlock_all(th->keeping_mutexes);
- th->keeping_mutexes = Qfalse;
+ th->keeping_mutexes = NULL;
}
/* delete self from living_threads */
@@ -2485,32 +2487,12 @@ 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) \
Data_Get_Struct(obj, mutex_t, tobj)
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
mutex_free(void *ptr)
{
if (ptr) {
@@ -2531,7 +2513,7 @@ mutex_alloc(VALUE klass)
VALUE volatile obj;
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_cond_initialize(&mutex->cond);
return obj;
@@ -2572,12 +2554,13 @@ rb_mutex_locked_p(VALUE self)
static void
mutex_locked(rb_thread_t *th, VALUE self)
{
+ mutex_t *mutex;
+ GetMutexPtr(self, mutex);
+
if (th->keeping_mutexes) {
- mutex_t *mutex;
- GetMutexPtr(self, mutex);
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);
if (!err) {
- GetMutexPtr(th->keeping_mutexes, th_mutex);
+ th_mutex = th->keeping_mutexes;
if (th_mutex == mutex) {
th->keeping_mutexes = mutex->next_mutex;
}
else {
while (1) {
mutex_t *tmp_mutex;
- GetMutexPtr(th_mutex->next_mutex, tmp_mutex);
+ tmp_mutex = th_mutex->next_mutex;
if (tmp_mutex == mutex) {
th_mutex->next_mutex = tmp_mutex->next_mutex;
break;
@@ -2785,13 +2768,13 @@ rb_mutex_unlock(VALUE self)
}
static void
-rb_mutex_unlock_all(VALUE mutexes)
+rb_mutex_unlock_all(mutex_t *mutexes)
{
const char *err;
mutex_t *mutex;
while (mutexes) {
- GetMutexPtr(mutexes, mutex);
+ mutex = mutexes;
/* rb_warn("mutex #<%s:%p> remains to be locked by terminated thread",
rb_obj_classname(mutexes), (void*)mutexes); */
mutexes = mutex->next_mutex;
diff --git a/vm.c b/vm.c
index 5cc4658290..6636a52258 100644
--- a/vm.c
+++ b/vm.c
@@ -1478,7 +1478,7 @@ thread_free(void *ptr)
if (th->locking_mutex != Qfalse) {
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);
}
@@ -1551,7 +1551,6 @@ rb_thread_mark(void *ptr)
RUBY_MARK_UNLESS_NULL(th->last_status);
RUBY_MARK_UNLESS_NULL(th->locking_mutex);
- RUBY_MARK_UNLESS_NULL(th->keeping_mutexes);
rb_mark_tbl(th->local_storage);
diff --git a/vm_core.h b/vm_core.h
index 7ac6bb1ceb..5a97d10edd 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -396,6 +396,8 @@ struct rb_unblock_callback {
void *arg;
};
+struct rb_mutex_struct;
+
struct rb_thread_struct
{
VALUE self;
@@ -443,7 +445,7 @@ struct rb_thread_struct
rb_thread_lock_t interrupt_lock;
struct rb_unblock_callback unblock;
VALUE locking_mutex;
- VALUE keeping_mutexes;
+ struct rb_mutex_struct *keeping_mutexes;
int transition_for_lock;
struct rb_vm_tag *tag;
@@ -496,6 +498,15 @@ struct rb_thread_struct
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 */
VALUE rb_iseq_new(NODE*, VALUE, VALUE, VALUE, VALUE);
VALUE rb_iseq_new_with_bopt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE);