CheckForDistributedDeadlocks no longer uses a VLA

- variable length arrays (VLAs) do not work with Visual Studio
- fix an off-by-one error. We incorrectly assumed there would always at
  least as many edges as there were nodes.
- refactor: reduce scope of transactionNodeStack by moving it into the
  function which uses it.
- refactor: break up the distinct uses of currentStackDepth into
  separate variables.
pull/1965/head
Brian Cloutier 2018-01-18 15:50:22 -08:00 committed by Brian Cloutier
parent 097fd15a89
commit 2efe80ce55
1 changed files with 16 additions and 5 deletions

View File

@ -135,6 +135,12 @@ CheckForDistributedDeadlocks(void)
bool deadlockFound = false;
List *deadlockPath = NIL;
/*
* Since we only see nodes which are waiting or being waited upon it's not
* possible to have more than edgeCount + 1 nodes.
*/
int maxStackDepth = edgeCount + 1;
/* we're only interested in finding deadlocks originating from this node */
if (transactionNode->transactionId.initiatorNodeIdentifier != localGroupId)
{
@ -144,7 +150,7 @@ CheckForDistributedDeadlocks(void)
ResetVisitedFields(adjacencyLists);
deadlockFound = CheckDeadlockForTransactionNode(transactionNode,
edgeCount,
maxStackDepth,
&deadlockPath);
if (deadlockFound)
{
@ -233,22 +239,24 @@ CheckDeadlockForTransactionNode(TransactionNode *startingTransactionNode,
List **deadlockPath)
{
List *toBeVisitedNodes = NIL;
int currentStackDepth = 0;
TransactionNode *transactionNodeStack[maxStackDepth];
const int rootStackDepth = 0;
TransactionNode **transactionNodeStack =
palloc0(maxStackDepth * sizeof(TransactionNode *));
/*
* We keep transactionNodeStack to keep track of the deadlock paths. At this point,
* adjust the depth of the starting node and set the stack's first element with
* the starting node.
*/
transactionNodeStack[currentStackDepth] = startingTransactionNode;
transactionNodeStack[rootStackDepth] = startingTransactionNode;
PrependOutgoingNodesToQueue(startingTransactionNode, currentStackDepth,
PrependOutgoingNodesToQueue(startingTransactionNode, rootStackDepth,
&toBeVisitedNodes);
/* traverse the graph and search for the deadlocks */
while (toBeVisitedNodes != NIL)
{
int currentStackDepth;
QueuedTransactionNode *queuedTransactionNode =
(QueuedTransactionNode *) linitial(toBeVisitedNodes);
TransactionNode *currentTransactionNode = queuedTransactionNode->transactionNode;
@ -261,6 +269,7 @@ CheckDeadlockForTransactionNode(TransactionNode *startingTransactionNode,
BuildDeadlockPathList(queuedTransactionNode, transactionNodeStack,
deadlockPath);
pfree(transactionNodeStack);
return true;
}
@ -274,12 +283,14 @@ CheckDeadlockForTransactionNode(TransactionNode *startingTransactionNode,
/* set the stack's corresponding element with the current node */
currentStackDepth = queuedTransactionNode->currentStackDepth;
Assert(currentStackDepth < maxStackDepth);
transactionNodeStack[currentStackDepth] = currentTransactionNode;
PrependOutgoingNodesToQueue(currentTransactionNode, currentStackDepth,
&toBeVisitedNodes);
}
pfree(transactionNodeStack);
return false;
}