From 619c191e442e896d80d23c62b343aee570947ef8 Mon Sep 17 00:00:00 2001 From: roytam1 Date: Fri, 16 Jul 2021 10:38:12 +0800 Subject: [PATCH] import changes from UXP: - [NSPR] Lock access to PRCallOnceType members in PR_CallOnce* for thread safety. (361743b22) --- nsprpub/pr/src/misc/prinit.c | 46 +++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/nsprpub/pr/src/misc/prinit.c b/nsprpub/pr/src/misc/prinit.c index 5ac99fe588..a952ad6554 100644 --- a/nsprpub/pr/src/misc/prinit.c +++ b/nsprpub/pr/src/misc/prinit.c @@ -771,10 +771,15 @@ PR_IMPLEMENT(PRStatus) PR_CallOnce( _PR_ImplicitInitialization(); } - if (!once->initialized) { + PR_Lock(mod_init.ml); + PRIntn initialized = once->initialized; + PRStatus status = once->status; + PR_Unlock(mod_init.ml); + if (!initialized) { if (PR_ATOMIC_SET(&once->inProgress, 1) == 0) { - once->status = (*func)(); + status = (*func)(); PR_Lock(mod_init.ml); + once->status = status; once->initialized = 1; PR_NotifyAllCondVar(mod_init.cv); PR_Unlock(mod_init.ml); @@ -783,14 +788,18 @@ PR_IMPLEMENT(PRStatus) PR_CallOnce( while (!once->initialized) { PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT); } + status = once->status; PR_Unlock(mod_init.ml); + if (PR_SUCCESS != status) { + PR_SetError(PR_CALL_ONCE_ERROR, 0); + } } - } else { - if (PR_SUCCESS != once->status) { - PR_SetError(PR_CALL_ONCE_ERROR, 0); - } + return status; } - return once->status; + if (PR_SUCCESS != status) { + PR_SetError(PR_CALL_ONCE_ERROR, 0); + } + return status; } PR_IMPLEMENT(PRStatus) PR_CallOnceWithArg( @@ -802,10 +811,15 @@ PR_IMPLEMENT(PRStatus) PR_CallOnceWithArg( _PR_ImplicitInitialization(); } - if (!once->initialized) { + PR_Lock(mod_init.ml); + PRIntn initialized = once->initialized; + PRStatus status = once->status; + PR_Unlock(mod_init.ml); + if (!initialized) { if (PR_ATOMIC_SET(&once->inProgress, 1) == 0) { - once->status = (*func)(arg); + status = (*func)(arg); PR_Lock(mod_init.ml); + once->status = status; once->initialized = 1; PR_NotifyAllCondVar(mod_init.cv); PR_Unlock(mod_init.ml); @@ -814,14 +828,18 @@ PR_IMPLEMENT(PRStatus) PR_CallOnceWithArg( while (!once->initialized) { PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT); } + status = once->status; PR_Unlock(mod_init.ml); + if (PR_SUCCESS != status) { + PR_SetError(PR_CALL_ONCE_ERROR, 0); + } } - } else { - if (PR_SUCCESS != once->status) { - PR_SetError(PR_CALL_ONCE_ERROR, 0); - } + return status; } - return once->status; + if (PR_SUCCESS != status) { + PR_SetError(PR_CALL_ONCE_ERROR, 0); + } + return status; } PRBool _PR_Obsolete(const char *obsolete, const char *preferred)