Skip to content

Commit

Permalink
mono_runtime_class_init_full: handle spurious wakeups
Browse files Browse the repository at this point in the history
the condition variable may be signaled even if the initialization by
the other thread is not done yet.  Handle spurious wakeups the same
way as timeouts: go around once more from the beginning.

Fixes #96872
  • Loading branch information
lambdageek authored and github-actions committed Jan 12, 2024
1 parent 508b876 commit 5c6dfe2
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/mono/mono/metadata/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -615,8 +615,8 @@ mono_runtime_class_init_full (MonoVTable *vtable, MonoError *error)
if (!lock->done) {
int timeout_ms = 500;
int wait_result = mono_coop_cond_timedwait (&lock->cond, &lock->mutex, timeout_ms);
if (wait_result == -1) {
/* timed out - go around again from the beginning. If we got here
if (wait_result == -1 || (wait_result == 0 && !lock->done)) {
/* timed out or spurious wakeup - go around again from the beginning. If we got here
* from the "is_blocked = FALSE" case, above (another thread was
* blocked on the current thread, but on a lock that was already
* done but it didn't get to wake up yet), then it might still be
Expand Down Expand Up @@ -647,7 +647,7 @@ mono_runtime_class_init_full (MonoVTable *vtable, MonoError *error)
g_hash_table_remove (type_initialization_hash, vtable);
mono_type_initialization_unlock ();
goto retry_top;
} else if (wait_result == 0) {
} else if (wait_result == 0 && lock->done) {
/* Success: we were signaled that the other thread is done. Proceed */
} else {
g_assert_not_reached ();
Expand Down

0 comments on commit 5c6dfe2

Please sign in to comment.