* thread.c (mutex_free): GC thread (main thread) has failed to unlock

a mutex that is locked by another thread, which makes the mutex
  dangling in keeping_mutexes and causes [BUG] or stuck finally.
  Now unlocking is performed as locking thread.

* thread.c (mutex_unlock, rb_mutex_unlock, rb_mutex_unlock_all):
  mutex_unlock receives a thread.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@21105 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
mame 2008-12-28 01:39:18 +00:00
parent 1cbf898172
commit 0e41458700
2 changed files with 17 additions and 7 deletions

View File

@ -1,3 +1,13 @@
Sun Dec 28 10:28:04 2008 Yusuke Endoh <mame@tsg.ne.jp>
* thread.c (mutex_free): GC thread (main thread) has failed to unlock
a mutex that is locked by another thread, which makes the mutex
dangling in keeping_mutexes and causes [BUG] or stuck finally.
Now unlocking is performed as locking thread.
* thread.c (mutex_unlock, rb_mutex_unlock, rb_mutex_unlock_all):
mutex_unlock receives a thread.
Sun Dec 28 05:44:44 2008 Ryan Davis <ryan@wrath.local> Sun Dec 28 05:44:44 2008 Ryan Davis <ryan@wrath.local>
* lib/minitest/*.rb: Imported minitest 1.3.1 r4505. * lib/minitest/*.rb: Imported minitest 1.3.1 r4505.

View File

@ -2708,7 +2708,7 @@ thgroup_add(VALUE group, VALUE thread)
#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, rb_thread_t *th);
static void static void
mutex_free(void *ptr) mutex_free(void *ptr)
@ -2717,7 +2717,8 @@ mutex_free(void *ptr)
mutex_t *mutex = ptr; mutex_t *mutex = ptr;
if (mutex->th) { if (mutex->th) {
/* rb_warn("free locked mutex"); */ /* rb_warn("free locked mutex"); */
mutex_unlock(mutex); char *err = mutex_unlock(mutex, mutex->th);
if (err) rb_bug("%s", err);
} }
native_mutex_destroy(&mutex->lock); native_mutex_destroy(&mutex->lock);
native_cond_destroy(&mutex->cond); native_cond_destroy(&mutex->cond);
@ -2917,10 +2918,9 @@ rb_mutex_lock(VALUE self)
} }
static const char * static const char *
mutex_unlock(mutex_t *mutex) mutex_unlock(mutex_t *mutex, rb_thread_t *th)
{ {
const char *err = NULL; const char *err = NULL;
rb_thread_t *th = GET_THREAD();
mutex_t *th_mutex; mutex_t *th_mutex;
native_mutex_lock(&mutex->lock); native_mutex_lock(&mutex->lock);
@ -2928,7 +2928,7 @@ mutex_unlock(mutex_t *mutex)
if (mutex->th == 0) { if (mutex->th == 0) {
err = "Attempt to unlock a mutex which is not locked"; err = "Attempt to unlock a mutex which is not locked";
} }
else if (mutex->th != GET_THREAD()) { else if (mutex->th != th) {
err = "Attempt to unlock a mutex which is locked by another thread"; err = "Attempt to unlock a mutex which is locked by another thread";
} }
else { else {
@ -2979,7 +2979,7 @@ rb_mutex_unlock(VALUE self)
mutex_t *mutex; mutex_t *mutex;
GetMutexPtr(self, mutex); GetMutexPtr(self, mutex);
err = mutex_unlock(mutex); err = mutex_unlock(mutex, GET_THREAD());
if (err) rb_raise(rb_eThreadError, "%s", err); if (err) rb_raise(rb_eThreadError, "%s", err);
return self; return self;
@ -2996,7 +2996,7 @@ rb_mutex_unlock_all(mutex_t *mutexes)
/* rb_warn("mutex #<%p> remains to be locked by terminated thread", /* rb_warn("mutex #<%p> remains to be locked by terminated thread",
mutexes); */ mutexes); */
mutexes = mutex->next_mutex; mutexes = mutex->next_mutex;
err = mutex_unlock(mutex); err = mutex_unlock(mutex, GET_THREAD());
if (err) rb_bug("invalid keeping_mutexes: %s", err); if (err) rb_bug("invalid keeping_mutexes: %s", err);
} }
} }