diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-01-22 02:59:24 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-01-22 02:59:24 +0000 |
commit | 47ba04ab544664fefe22f0e49e2307647bc33af5 (patch) | |
tree | 58887361507ba23f1681fa01255148350d978908 /libgo/runtime | |
parent | 039868965d6679379f1b87b7336986605229430b (diff) | |
download | gcc-47ba04ab544664fefe22f0e49e2307647bc33af5.tar.gz |
Avoid crash when M structure free just before thread exit.
From-SVN: r169121
Diffstat (limited to 'libgo/runtime')
-rw-r--r-- | libgo/runtime/go-go.c | 7 | ||||
-rw-r--r-- | libgo/runtime/thread.c | 16 |
2 files changed, 17 insertions, 6 deletions
diff --git a/libgo/runtime/go-go.c b/libgo/runtime/go-go.c index 31462685afb..8c2de2877cf 100644 --- a/libgo/runtime/go-go.c +++ b/libgo/runtime/go-go.c @@ -94,6 +94,13 @@ remove_current_thread (void) runtime_MCache_ReleaseAll (mcache); + /* As soon as we release this look, a GC could run. Since this + thread is no longer on the list, the GC will not find our M + structure, so it could get freed at any time. That means that + any code from here to thread exit must not assume that the m is + valid. */ + m = NULL; + i = pthread_mutex_unlock (&__go_thread_ids_lock); __go_assert (i == 0); diff --git a/libgo/runtime/thread.c b/libgo/runtime/thread.c index 99a0d68f03b..c4e7f6c72e0 100644 --- a/libgo/runtime/thread.c +++ b/libgo/runtime/thread.c @@ -38,9 +38,11 @@ runtime_lock_full(Lock *l) void runtime_lock(Lock *l) { - if(m->locks < 0) - runtime_throw("lock count"); - m->locks++; + if(m != nil) { + if(m->locks < 0) + runtime_throw("lock count"); + m->locks++; + } if(runtime_xadd(&l->key, 1) > 1) // someone else has it; wait runtime_lock_full(l); @@ -58,9 +60,11 @@ runtime_unlock_full(Lock *l) void runtime_unlock(Lock *l) { - m->locks--; - if(m->locks < 0) - runtime_throw("lock count"); + if(m != nil) { + m->locks--; + if(m->locks < 0) + runtime_throw("lock count"); + } if(runtime_xadd(&l->key, -1) > 0) // someone else is waiting runtime_unlock_full(l); |