|
|
744490 |
# HG changeset patch
|
|
|
744490 |
# User Daiki Ueno <dueno@redhat.com>
|
|
|
744490 |
# Date 1521731296 -3600
|
|
|
744490 |
# Thu Mar 22 16:08:16 2018 +0100
|
|
|
744490 |
# Node ID 6ae3ab8a1e7b4161f3f8eee90db7a745acced408
|
|
|
744490 |
# Parent dedf5290c679153e5b3555ba9c711fe62323c156
|
|
|
744490 |
Bug 1447628, devslot: avoid deadlock when re-inserting a token, r=rrelyea
|
|
|
744490 |
|
|
|
744490 |
diff --git a/lib/dev/devslot.c b/lib/dev/devslot.c
|
|
|
744490 |
--- a/lib/dev/devslot.c
|
|
|
744490 |
+++ b/lib/dev/devslot.c
|
|
|
744490 |
@@ -96,10 +96,16 @@ nssSlot_ResetDelay(
|
|
|
744490 |
}
|
|
|
744490 |
|
|
|
744490 |
static PRBool
|
|
|
744490 |
-within_token_delay_period(const NSSSlot *slot)
|
|
|
744490 |
+token_status_checked(const NSSSlot *slot)
|
|
|
744490 |
{
|
|
|
744490 |
PRIntervalTime time;
|
|
|
744490 |
int lastPingState = slot->lastTokenPingState;
|
|
|
744490 |
+ /* When called from the same thread, that means
|
|
|
744490 |
+ * nssSlot_IsTokenPresent() is called recursively through
|
|
|
744490 |
+ * nssSlot_Refresh(). Return immediately in that case. */
|
|
|
744490 |
+ if (slot->isPresentThread == PR_GetCurrentThread()) {
|
|
|
744490 |
+ return PR_TRUE;
|
|
|
744490 |
+ }
|
|
|
744490 |
/* Set the delay time for checking the token presence */
|
|
|
744490 |
if (s_token_delay_time == 0) {
|
|
|
744490 |
s_token_delay_time = PR_SecondsToInterval(NSSSLOT_TOKEN_DELAY_TIME);
|
|
|
744490 |
@@ -130,7 +136,7 @@ nssSlot_IsTokenPresent(
|
|
|
744490 |
|
|
|
744490 |
/* avoid repeated calls to check token status within set interval */
|
|
|
744490 |
PZ_Lock(slot->isPresentLock);
|
|
|
744490 |
- if (within_token_delay_period(slot)) {
|
|
|
744490 |
+ if (token_status_checked(slot)) {
|
|
|
744490 |
CK_FLAGS ckFlags = slot->ckFlags;
|
|
|
744490 |
PZ_Unlock(slot->isPresentLock);
|
|
|
744490 |
return ((ckFlags & CKF_TOKEN_PRESENT) != 0);
|
|
|
744490 |
@@ -146,12 +152,12 @@ nssSlot_IsTokenPresent(
|
|
|
744490 |
|
|
|
744490 |
/* set up condition so only one thread is active in this part of the code at a time */
|
|
|
744490 |
PZ_Lock(slot->isPresentLock);
|
|
|
744490 |
- while (slot->inIsPresent) {
|
|
|
744490 |
+ while (slot->isPresentThread) {
|
|
|
744490 |
PR_WaitCondVar(slot->isPresentCondition, 0);
|
|
|
744490 |
}
|
|
|
744490 |
/* if we were one of multiple threads here, the first thread will have
|
|
|
744490 |
* given us the answer, no need to make more queries of the token. */
|
|
|
744490 |
- if (within_token_delay_period(slot)) {
|
|
|
744490 |
+ if (token_status_checked(slot)) {
|
|
|
744490 |
CK_FLAGS ckFlags = slot->ckFlags;
|
|
|
744490 |
PZ_Unlock(slot->isPresentLock);
|
|
|
744490 |
return ((ckFlags & CKF_TOKEN_PRESENT) != 0);
|
|
|
744490 |
@@ -159,7 +165,7 @@ nssSlot_IsTokenPresent(
|
|
|
744490 |
/* this is the winning thread, block all others until we've determined
|
|
|
744490 |
* if the token is present and that it needs initialization. */
|
|
|
744490 |
slot->lastTokenPingState = nssSlotLastPingState_Update;
|
|
|
744490 |
- slot->inIsPresent = PR_TRUE;
|
|
|
744490 |
+ slot->isPresentThread = PR_GetCurrentThread();
|
|
|
744490 |
|
|
|
744490 |
PZ_Unlock(slot->isPresentLock);
|
|
|
744490 |
|
|
|
744490 |
@@ -257,7 +263,7 @@ done:
|
|
|
744490 |
slot->lastTokenPingTime = PR_IntervalNow();
|
|
|
744490 |
slot->lastTokenPingState = nssSlotLastPingState_Valid;
|
|
|
744490 |
}
|
|
|
744490 |
- slot->inIsPresent = PR_FALSE;
|
|
|
744490 |
+ slot->isPresentThread = NULL;
|
|
|
744490 |
PR_NotifyAllCondVar(slot->isPresentCondition);
|
|
|
744490 |
PZ_Unlock(slot->isPresentLock);
|
|
|
744490 |
return isPresent;
|
|
|
744490 |
diff --git a/lib/dev/devt.h b/lib/dev/devt.h
|
|
|
744490 |
--- a/lib/dev/devt.h
|
|
|
744490 |
+++ b/lib/dev/devt.h
|
|
|
744490 |
@@ -92,7 +92,7 @@ struct NSSSlotStr {
|
|
|
744490 |
PK11SlotInfo *pk11slot;
|
|
|
744490 |
PZLock *isPresentLock;
|
|
|
744490 |
PRCondVar *isPresentCondition;
|
|
|
744490 |
- PRBool inIsPresent;
|
|
|
744490 |
+ PRThread *isPresentThread;
|
|
|
744490 |
};
|
|
|
744490 |
|
|
|
744490 |
struct nssSessionStr {
|
|
|
744490 |
diff --git a/lib/pk11wrap/dev3hack.c b/lib/pk11wrap/dev3hack.c
|
|
|
744490 |
--- a/lib/pk11wrap/dev3hack.c
|
|
|
744490 |
+++ b/lib/pk11wrap/dev3hack.c
|
|
|
744490 |
@@ -122,7 +122,7 @@ nssSlot_CreateFromPK11SlotInfo(NSSTrustD
|
|
|
744490 |
rvSlot->lock = (nss3slot->isThreadSafe) ? NULL : nss3slot->sessionLock;
|
|
|
744490 |
rvSlot->isPresentLock = PZ_NewLock(nssiLockOther);
|
|
|
744490 |
rvSlot->isPresentCondition = PR_NewCondVar(rvSlot->isPresentLock);
|
|
|
744490 |
- rvSlot->inIsPresent = PR_FALSE;
|
|
|
744490 |
+ rvSlot->isPresentThread = NULL;
|
|
|
744490 |
rvSlot->lastTokenPingState = nssSlotLastPingState_Reset;
|
|
|
744490 |
return rvSlot;
|
|
|
744490 |
}
|