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 dotnet#96872
  • Loading branch information
lambdageek committed Jan 12, 2024
1 parent 54530c7 commit 49a18a4
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 @@ -614,8 +614,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 @@ -646,7 +646,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 49a18a4

Please sign in to comment.