mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-29 20:07:30 +09:00
[NSPR] Lock access to PRCallOnceType members in PR_CallOnce* for thread safety.
Cherry-picked upstream fix from 4.31
This commit is contained in:
parent
d3f293ec09
commit
bfac131dc2
1 changed files with 32 additions and 14 deletions
|
|
@ -771,10 +771,15 @@ PR_IMPLEMENT(PRStatus) PR_CallOnce(
|
||||||
_PR_ImplicitInitialization();
|
_PR_ImplicitInitialization();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!once->initialized) {
|
|
||||||
if (PR_ATOMIC_SET(&once->inProgress, 1) == 0) {
|
|
||||||
once->status = (*func)();
|
|
||||||
PR_Lock(mod_init.ml);
|
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) {
|
||||||
|
status = (*func)();
|
||||||
|
PR_Lock(mod_init.ml);
|
||||||
|
once->status = status;
|
||||||
once->initialized = 1;
|
once->initialized = 1;
|
||||||
PR_NotifyAllCondVar(mod_init.cv);
|
PR_NotifyAllCondVar(mod_init.cv);
|
||||||
PR_Unlock(mod_init.ml);
|
PR_Unlock(mod_init.ml);
|
||||||
|
|
@ -783,14 +788,18 @@ PR_IMPLEMENT(PRStatus) PR_CallOnce(
|
||||||
while (!once->initialized) {
|
while (!once->initialized) {
|
||||||
PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT);
|
PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
status = once->status;
|
||||||
PR_Unlock(mod_init.ml);
|
PR_Unlock(mod_init.ml);
|
||||||
}
|
if (PR_SUCCESS != status) {
|
||||||
} else {
|
|
||||||
if (PR_SUCCESS != once->status) {
|
|
||||||
PR_SetError(PR_CALL_ONCE_ERROR, 0);
|
PR_SetError(PR_CALL_ONCE_ERROR, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return once->status;
|
return status;
|
||||||
|
}
|
||||||
|
if (PR_SUCCESS != status) {
|
||||||
|
PR_SetError(PR_CALL_ONCE_ERROR, 0);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
PR_IMPLEMENT(PRStatus) PR_CallOnceWithArg(
|
PR_IMPLEMENT(PRStatus) PR_CallOnceWithArg(
|
||||||
|
|
@ -802,10 +811,15 @@ PR_IMPLEMENT(PRStatus) PR_CallOnceWithArg(
|
||||||
_PR_ImplicitInitialization();
|
_PR_ImplicitInitialization();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!once->initialized) {
|
|
||||||
if (PR_ATOMIC_SET(&once->inProgress, 1) == 0) {
|
|
||||||
once->status = (*func)(arg);
|
|
||||||
PR_Lock(mod_init.ml);
|
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) {
|
||||||
|
status = (*func)(arg);
|
||||||
|
PR_Lock(mod_init.ml);
|
||||||
|
once->status = status;
|
||||||
once->initialized = 1;
|
once->initialized = 1;
|
||||||
PR_NotifyAllCondVar(mod_init.cv);
|
PR_NotifyAllCondVar(mod_init.cv);
|
||||||
PR_Unlock(mod_init.ml);
|
PR_Unlock(mod_init.ml);
|
||||||
|
|
@ -814,14 +828,18 @@ PR_IMPLEMENT(PRStatus) PR_CallOnceWithArg(
|
||||||
while (!once->initialized) {
|
while (!once->initialized) {
|
||||||
PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT);
|
PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
status = once->status;
|
||||||
PR_Unlock(mod_init.ml);
|
PR_Unlock(mod_init.ml);
|
||||||
}
|
if (PR_SUCCESS != status) {
|
||||||
} else {
|
|
||||||
if (PR_SUCCESS != once->status) {
|
|
||||||
PR_SetError(PR_CALL_ONCE_ERROR, 0);
|
PR_SetError(PR_CALL_ONCE_ERROR, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return once->status;
|
return status;
|
||||||
|
}
|
||||||
|
if (PR_SUCCESS != status) {
|
||||||
|
PR_SetError(PR_CALL_ONCE_ERROR, 0);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool _PR_Obsolete(const char *obsolete, const char *preferred)
|
PRBool _PR_Obsolete(const char *obsolete, const char *preferred)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue