#define NPREDICATELOCKTARGETENTS() \
mul_size(max_predicate_locks_per_xact, add_size(MaxBackends, max_prepared_xacts))
-#define SxactIsOnFinishedList(sxact) (!SHMQueueIsDetached(&((sxact)->finishedLink)))
+#define SxactIsOnFinishedList(sxact) (!dlist_node_is_detached(&(sxact)->finishedLink))
/*
* Note that a sxact is marked "prepared" once it has passed
static HTAB *SerializableXidHash;
static HTAB *PredicateLockTargetHash;
static HTAB *PredicateLockHash;
-static SHM_QUEUE *FinishedSerializableTransactions;
+static dlist_head *FinishedSerializableTransactions;
/*
* Tag for a dummy entry in PredicateLockTargetHash. By temporarily removing
static SERIALIZABLEXACT *CreatePredXact(void);
static void ReleasePredXact(SERIALIZABLEXACT *sxact);
-static SERIALIZABLEXACT *FirstPredXact(void);
-static SERIALIZABLEXACT *NextPredXact(SERIALIZABLEXACT *sxact);
static bool RWConflictExists(const SERIALIZABLEXACT *reader, const SERIALIZABLEXACT *writer);
static void SetRWConflict(SERIALIZABLEXACT *reader, SERIALIZABLEXACT *writer);
static SERIALIZABLEXACT *
CreatePredXact(void)
{
- PredXactListElement ptle;
+ SERIALIZABLEXACT *sxact;
- ptle = (PredXactListElement)
- SHMQueueNext(&PredXact->availableList,
- &PredXact->availableList,
- offsetof(PredXactListElementData, link));
- if (!ptle)
+ if (dlist_is_empty(&PredXact->availableList))
return NULL;
- SHMQueueDelete(&ptle->link);
- SHMQueueInsertBefore(&PredXact->activeList, &ptle->link);
- return &ptle->sxact;
+ sxact = dlist_container(SERIALIZABLEXACT, xactLink,
+ dlist_pop_head_node(&PredXact->availableList));
+ dlist_push_tail(&PredXact->activeList, &sxact->xactLink);
+ return sxact;
}
static void
ReleasePredXact(SERIALIZABLEXACT *sxact)
{
- PredXactListElement ptle;
-
Assert(ShmemAddrIsValid(sxact));
- ptle = (PredXactListElement)
- (((char *) sxact)
- - offsetof(PredXactListElementData, sxact)
- + offsetof(PredXactListElementData, link));
- SHMQueueDelete(&ptle->link);
- SHMQueueInsertBefore(&PredXact->availableList, &ptle->link);
-}
-
-static SERIALIZABLEXACT *
-FirstPredXact(void)
-{
- PredXactListElement ptle;
-
- ptle = (PredXactListElement)
- SHMQueueNext(&PredXact->activeList,
- &PredXact->activeList,
- offsetof(PredXactListElementData, link));
- if (!ptle)
- return NULL;
-
- return &ptle->sxact;
-}
-
-static SERIALIZABLEXACT *
-NextPredXact(SERIALIZABLEXACT *sxact)
-{
- PredXactListElement ptle;
-
- Assert(ShmemAddrIsValid(sxact));
-
- ptle = (PredXactListElement)
- (((char *) sxact)
- - offsetof(PredXactListElementData, sxact)
- + offsetof(PredXactListElementData, link));
- ptle = (PredXactListElement)
- SHMQueueNext(&PredXact->activeList,
- &ptle->link,
- offsetof(PredXactListElementData, link));
- if (!ptle)
- return NULL;
-
- return &ptle->sxact;
+ dlist_delete(&sxact->xactLink);
+ dlist_push_tail(&PredXact->availableList, &sxact->xactLink);
}
/*------------------------------------------------------------------------*/
static bool
RWConflictExists(const SERIALIZABLEXACT *reader, const SERIALIZABLEXACT *writer)
{
- RWConflict conflict;
+ dlist_iter iter;
Assert(reader != writer);
/* Check the ends of the purported conflict first. */
if (SxactIsDoomed(reader)
|| SxactIsDoomed(writer)
- || SHMQueueEmpty(&reader->outConflicts)
- || SHMQueueEmpty(&writer->inConflicts))
+ || dlist_is_empty(&reader->outConflicts)
+ || dlist_is_empty(&writer->inConflicts))
return false;
- /* A conflict is possible; walk the list to find out. */
- conflict = (RWConflict)
- SHMQueueNext(&reader->outConflicts,
- &reader->outConflicts,
- offsetof(RWConflictData, outLink));
- while (conflict)
+ /*
+ * A conflict is possible; walk the list to find out.
+ *
+ * The unconstify is needed as we have no const version of
+ * dlist_foreach().
+ */
+ dlist_foreach(iter, &unconstify(SERIALIZABLEXACT *, reader)->outConflicts)
{
+ RWConflict conflict =
+ dlist_container(RWConflictData, outLink, iter.cur);
+
if (conflict->sxactIn == writer)
return true;
- conflict = (RWConflict)
- SHMQueueNext(&reader->outConflicts,
- &conflict->outLink,
- offsetof(RWConflictData, outLink));
}
/* No conflict found. */
Assert(reader != writer);
Assert(!RWConflictExists(reader, writer));
- conflict = (RWConflict)
- SHMQueueNext(&RWConflictPool->availableList,
- &RWConflictPool->availableList,
- offsetof(RWConflictData, outLink));
- if (!conflict)
+ if (dlist_is_empty(&RWConflictPool->availableList))
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("not enough elements in RWConflictPool to record a read/write conflict"),
errhint("You might need to run fewer transactions at a time or increase max_connections.")));
- SHMQueueDelete(&conflict->outLink);
+ conflict = dlist_head_element(RWConflictData, outLink, &RWConflictPool->availableList);
+ dlist_delete(&conflict->outLink);
conflict->sxactOut = reader;
conflict->sxactIn = writer;
- SHMQueueInsertBefore(&reader->outConflicts, &conflict->outLink);
- SHMQueueInsertBefore(&writer->inConflicts, &conflict->inLink);
+ dlist_push_tail(&reader->outConflicts, &conflict->outLink);
+ dlist_push_tail(&writer->inConflicts, &conflict->inLink);
}
static void
Assert(SxactIsReadOnly(roXact));
Assert(!SxactIsReadOnly(activeXact));
- conflict = (RWConflict)
- SHMQueueNext(&RWConflictPool->availableList,
- &RWConflictPool->availableList,
- offsetof(RWConflictData, outLink));
- if (!conflict)
+ if (dlist_is_empty(&RWConflictPool->availableList))
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("not enough elements in RWConflictPool to record a potential read/write conflict"),
errhint("You might need to run fewer transactions at a time or increase max_connections.")));
- SHMQueueDelete(&conflict->outLink);
+ conflict = dlist_head_element(RWConflictData, outLink, &RWConflictPool->availableList);
+ dlist_delete(&conflict->outLink);
conflict->sxactOut = activeXact;
conflict->sxactIn = roXact;
- SHMQueueInsertBefore(&activeXact->possibleUnsafeConflicts,
- &conflict->outLink);
- SHMQueueInsertBefore(&roXact->possibleUnsafeConflicts,
- &conflict->inLink);
+ dlist_push_tail(&activeXact->possibleUnsafeConflicts, &conflict->outLink);
+ dlist_push_tail(&roXact->possibleUnsafeConflicts, &conflict->inLink);
}
static void
ReleaseRWConflict(RWConflict conflict)
{
- SHMQueueDelete(&conflict->inLink);
- SHMQueueDelete(&conflict->outLink);
- SHMQueueInsertBefore(&RWConflictPool->availableList, &conflict->outLink);
+ dlist_delete(&conflict->inLink);
+ dlist_delete(&conflict->outLink);
+ dlist_push_tail(&RWConflictPool->availableList, &conflict->outLink);
}
static void
FlagSxactUnsafe(SERIALIZABLEXACT *sxact)
{
- RWConflict conflict,
- nextConflict;
+ dlist_mutable_iter iter;
Assert(SxactIsReadOnly(sxact));
Assert(!SxactIsROSafe(sxact));
* We know this isn't a safe snapshot, so we can stop looking for other
* potential conflicts.
*/
- conflict = (RWConflict)
- SHMQueueNext(&sxact->possibleUnsafeConflicts,
- &sxact->possibleUnsafeConflicts,
- offsetof(RWConflictData, inLink));
- while (conflict)
+ dlist_foreach_modify(iter, &sxact->possibleUnsafeConflicts)
{
- nextConflict = (RWConflict)
- SHMQueueNext(&sxact->possibleUnsafeConflicts,
- &conflict->inLink,
- offsetof(RWConflictData, inLink));
+ RWConflict conflict =
+ dlist_container(RWConflictData, inLink, iter.cur);
Assert(!SxactIsReadOnly(conflict->sxactOut));
Assert(sxact == conflict->sxactIn);
ReleaseRWConflict(conflict);
-
- conflict = nextConflict;
}
}
{
int i;
- SHMQueueInit(&PredXact->availableList);
- SHMQueueInit(&PredXact->activeList);
+ dlist_init(&PredXact->availableList);
+ dlist_init(&PredXact->activeList);
PredXact->SxactGlobalXmin = InvalidTransactionId;
PredXact->SxactGlobalXminCount = 0;
PredXact->WritableSxactCount = 0;
PredXact->CanPartialClearThrough = 0;
PredXact->HavePartialClearedThrough = 0;
requestSize = mul_size((Size) max_table_size,
- PredXactListElementDataSize);
+ sizeof(SERIALIZABLEXACT));
PredXact->element = ShmemAlloc(requestSize);
/* Add all elements to available list, clean. */
memset(PredXact->element, 0, requestSize);
for (i = 0; i < max_table_size; i++)
{
- LWLockInitialize(&PredXact->element[i].sxact.perXactPredicateListLock,
+ LWLockInitialize(&PredXact->element[i].perXactPredicateListLock,
LWTRANCHE_PER_XACT_PREDICATE_LIST);
- SHMQueueInsertBefore(&(PredXact->availableList),
- &(PredXact->element[i].link));
+ dlist_push_tail(&PredXact->availableList, &PredXact->element[i].xactLink);
}
PredXact->OldCommittedSxact = CreatePredXact();
SetInvalidVirtualTransactionId(PredXact->OldCommittedSxact->vxid);
PredXact->OldCommittedSxact->prepareSeqNo = 0;
PredXact->OldCommittedSxact->commitSeqNo = 0;
PredXact->OldCommittedSxact->SeqNo.lastCommitBeforeSnapshot = 0;
- SHMQueueInit(&PredXact->OldCommittedSxact->outConflicts);
- SHMQueueInit(&PredXact->OldCommittedSxact->inConflicts);
- SHMQueueInit(&PredXact->OldCommittedSxact->predicateLocks);
- SHMQueueInit(&PredXact->OldCommittedSxact->finishedLink);
- SHMQueueInit(&PredXact->OldCommittedSxact->possibleUnsafeConflicts);
+ dlist_init(&PredXact->OldCommittedSxact->outConflicts);
+ dlist_init(&PredXact->OldCommittedSxact->inConflicts);
+ dlist_init(&PredXact->OldCommittedSxact->predicateLocks);
+ dlist_node_init(&PredXact->OldCommittedSxact->finishedLink);
+ dlist_init(&PredXact->OldCommittedSxact->possibleUnsafeConflicts);
PredXact->OldCommittedSxact->topXid = InvalidTransactionId;
PredXact->OldCommittedSxact->finishedBefore = InvalidTransactionId;
PredXact->OldCommittedSxact->xmin = InvalidTransactionId;
{
int i;
- SHMQueueInit(&RWConflictPool->availableList);
+ dlist_init(&RWConflictPool->availableList);
requestSize = mul_size((Size) max_table_size,
RWConflictDataSize);
RWConflictPool->element = ShmemAlloc(requestSize);
memset(RWConflictPool->element, 0, requestSize);
for (i = 0; i < max_table_size; i++)
{
- SHMQueueInsertBefore(&(RWConflictPool->availableList),
- &(RWConflictPool->element[i].outLink));
+ dlist_push_tail(&RWConflictPool->availableList,
+ &RWConflictPool->element[i].outLink);
}
}
* Create or attach to the header for the list of finished serializable
* transactions.
*/
- FinishedSerializableTransactions = (SHM_QUEUE *)
+ FinishedSerializableTransactions = (dlist_head *)
ShmemInitStruct("FinishedSerializableTransactions",
- sizeof(SHM_QUEUE),
+ sizeof(dlist_head),
&found);
Assert(found == IsUnderPostmaster);
if (!found)
- SHMQueueInit(FinishedSerializableTransactions);
+ dlist_init(FinishedSerializableTransactions);
/*
* Initialize the SLRU storage for old committed serializable
max_table_size *= 10;
size = add_size(size, PredXactListDataSize);
size = add_size(size, mul_size((Size) max_table_size,
- PredXactListElementDataSize));
+ sizeof(SERIALIZABLEXACT)));
/* transaction xid table */
size = add_size(size, hash_estimate_size(max_table_size,
RWConflictDataSize));
/* Head for list of finished serializable transactions. */
- size = add_size(size, sizeof(SHM_QUEUE));
+ size = add_size(size, sizeof(dlist_head));
/* Shared memory structures for SLRU tracking of old committed xids. */
size = add_size(size, sizeof(SerialControlData));
* that case, we have nothing to do here. The caller will find one of the
* slots released by the other backend when it retries.
*/
- if (SHMQueueEmpty(FinishedSerializableTransactions))
+ if (dlist_is_empty(FinishedSerializableTransactions))
{
LWLockRelease(SerializableFinishedListLock);
return;
* Grab the first sxact off the finished list -- this will be the earliest
* commit. Remove it from the list.
*/
- sxact = (SERIALIZABLEXACT *)
- SHMQueueNext(FinishedSerializableTransactions,
- FinishedSerializableTransactions,
- offsetof(SERIALIZABLEXACT, finishedLink));
- SHMQueueDelete(&(sxact->finishedLink));
+ sxact = dlist_head_element(SERIALIZABLEXACT, finishedLink,
+ FinishedSerializableTransactions);
+ dlist_delete_thoroughly(&sxact->finishedLink);
/* Add to SLRU summary information. */
if (TransactionIdIsValid(sxact->topXid) && !SxactIsReadOnly(sxact))
* them marked us as conflicted.
*/
MySerializableXact->flags |= SXACT_FLAG_DEFERRABLE_WAITING;
- while (!(SHMQueueEmpty(&MySerializableXact->possibleUnsafeConflicts) ||
+ while (!(dlist_is_empty(&MySerializableXact->possibleUnsafeConflicts) ||
SxactIsROUnsafe(MySerializableXact)))
{
LWLockRelease(SerializableXactHashLock);
GetSafeSnapshotBlockingPids(int blocked_pid, int *output, int output_size)
{
int num_written = 0;
- SERIALIZABLEXACT *sxact;
+ dlist_iter iter;
+ SERIALIZABLEXACT *sxact = NULL;
LWLockAcquire(SerializableXactHashLock, LW_SHARED);
/* Find blocked_pid's SERIALIZABLEXACT by linear search. */
- for (sxact = FirstPredXact(); sxact != NULL; sxact = NextPredXact(sxact))
+ dlist_foreach(iter, &PredXact->activeList)
{
+ sxact = dlist_container(SERIALIZABLEXACT, xactLink, iter.cur);
+
if (sxact->pid == blocked_pid)
break;
}
/* Did we find it, and is it currently waiting in GetSafeSnapshot? */
if (sxact != NULL && SxactIsDeferrableWaiting(sxact))
{
- RWConflict possibleUnsafeConflict;
-
/* Traverse the list of possible unsafe conflicts collecting PIDs. */
- possibleUnsafeConflict = (RWConflict)
- SHMQueueNext(&sxact->possibleUnsafeConflicts,
- &sxact->possibleUnsafeConflicts,
- offsetof(RWConflictData, inLink));
-
- while (possibleUnsafeConflict != NULL && num_written < output_size)
+ dlist_foreach(iter, &sxact->possibleUnsafeConflicts)
{
+ RWConflict possibleUnsafeConflict =
+ dlist_container(RWConflictData, inLink, iter.cur);
+
output[num_written++] = possibleUnsafeConflict->sxactOut->pid;
- possibleUnsafeConflict = (RWConflict)
- SHMQueueNext(&sxact->possibleUnsafeConflicts,
- &possibleUnsafeConflict->inLink,
- offsetof(RWConflictData, inLink));
}
}
sxact->SeqNo.lastCommitBeforeSnapshot = PredXact->LastSxactCommitSeqNo;
sxact->prepareSeqNo = InvalidSerCommitSeqNo;
sxact->commitSeqNo = InvalidSerCommitSeqNo;
- SHMQueueInit(&(sxact->outConflicts));
- SHMQueueInit(&(sxact->inConflicts));
- SHMQueueInit(&(sxact->possibleUnsafeConflicts));
+ dlist_init(&(sxact->outConflicts));
+ dlist_init(&(sxact->inConflicts));
+ dlist_init(&(sxact->possibleUnsafeConflicts));
sxact->topXid = GetTopTransactionIdIfAny();
sxact->finishedBefore = InvalidTransactionId;
sxact->xmin = snapshot->xmin;
sxact->pid = MyProcPid;
sxact->pgprocno = MyProc->pgprocno;
- SHMQueueInit(&(sxact->predicateLocks));
- SHMQueueElemInit(&(sxact->finishedLink));
+ dlist_init(&sxact->predicateLocks);
+ dlist_node_init(&sxact->finishedLink);
sxact->flags = 0;
if (XactReadOnly)
{
+ dlist_iter iter;
+
sxact->flags |= SXACT_FLAG_READ_ONLY;
/*
* transactions then this snapshot can be deemed safe (and we can run
* without tracking predicate locks).
*/
- for (othersxact = FirstPredXact();
- othersxact != NULL;
- othersxact = NextPredXact(othersxact))
+ dlist_foreach(iter, &PredXact->activeList)
{
+ othersxact = dlist_container(SERIALIZABLEXACT, xactLink, iter.cur);
+
if (!SxactIsCommitted(othersxact)
&& !SxactIsDoomed(othersxact)
&& !SxactIsReadOnly(othersxact))
Assert(LWLockHeldByMe(SerializablePredicateListLock));
/* Can't remove it until no locks at this target. */
- if (!SHMQueueEmpty(&target->predicateLocks))
+ if (!dlist_is_empty(&target->predicateLocks))
return;
/* Actually remove the target. */
{
SERIALIZABLEXACT *sxact;
PREDICATELOCK *predlock;
+ dlist_mutable_iter iter;
LWLockAcquire(SerializablePredicateListLock, LW_SHARED);
sxact = MySerializableXact;
if (IsInParallelMode())
LWLockAcquire(&sxact->perXactPredicateListLock, LW_EXCLUSIVE);
- predlock = (PREDICATELOCK *)
- SHMQueueNext(&(sxact->predicateLocks),
- &(sxact->predicateLocks),
- offsetof(PREDICATELOCK, xactLink));
- while (predlock)
+
+ dlist_foreach_modify(iter, &sxact->predicateLocks)
{
- SHM_QUEUE *predlocksxactlink;
- PREDICATELOCK *nextpredlock;
PREDICATELOCKTAG oldlocktag;
PREDICATELOCKTARGET *oldtarget;
PREDICATELOCKTARGETTAG oldtargettag;
- predlocksxactlink = &(predlock->xactLink);
- nextpredlock = (PREDICATELOCK *)
- SHMQueueNext(&(sxact->predicateLocks),
- predlocksxactlink,
- offsetof(PREDICATELOCK, xactLink));
+ predlock = dlist_container(PREDICATELOCK, xactLink, iter.cur);
oldlocktag = predlock->tag;
Assert(oldlocktag.myXact == sxact);
LWLockAcquire(partitionLock, LW_EXCLUSIVE);
- SHMQueueDelete(predlocksxactlink);
- SHMQueueDelete(&(predlock->targetLink));
+ dlist_delete(&predlock->xactLink);
+ dlist_delete(&predlock->targetLink);
rmpredlock = hash_search_with_hash_value
(PredicateLockHash,
&oldlocktag,
DecrementParentLocks(&oldtargettag);
}
-
- predlock = nextpredlock;
}
if (IsInParallelMode())
LWLockRelease(&sxact->perXactPredicateListLock);
errmsg("out of shared memory"),
errhint("You might need to increase max_pred_locks_per_transaction.")));
if (!found)
- SHMQueueInit(&(target->predicateLocks));
+ dlist_init(&target->predicateLocks);
/* We've got the sxact and target, make sure they're joined. */
locktag.myTarget = target;
if (!found)
{
- SHMQueueInsertBefore(&(target->predicateLocks), &(lock->targetLink));
- SHMQueueInsertBefore(&(sxact->predicateLocks),
- &(lock->xactLink));
+ dlist_push_tail(&target->predicateLocks, &lock->targetLink);
+ dlist_push_tail(&sxact->predicateLocks, &lock->xactLink);
lock->commitSeqNo = InvalidSerCommitSeqNo;
}
static void
DeleteLockTarget(PREDICATELOCKTARGET *target, uint32 targettaghash)
{
- PREDICATELOCK *predlock;
- SHM_QUEUE *predlocktargetlink;
- PREDICATELOCK *nextpredlock;
- bool found;
+ dlist_mutable_iter iter;
Assert(LWLockHeldByMeInMode(SerializablePredicateListLock,
LW_EXCLUSIVE));
Assert(LWLockHeldByMe(PredicateLockHashPartitionLock(targettaghash)));
- predlock = (PREDICATELOCK *)
- SHMQueueNext(&(target->predicateLocks),
- &(target->predicateLocks),
- offsetof(PREDICATELOCK, targetLink));
LWLockAcquire(SerializableXactHashLock, LW_EXCLUSIVE);
- while (predlock)
+
+ dlist_foreach_modify(iter, &target->predicateLocks)
{
- predlocktargetlink = &(predlock->targetLink);
- nextpredlock = (PREDICATELOCK *)
- SHMQueueNext(&(target->predicateLocks),
- predlocktargetlink,
- offsetof(PREDICATELOCK, targetLink));
+ PREDICATELOCK *predlock =
+ dlist_container(PREDICATELOCK, targetLink, iter.cur);
+ bool found;
- SHMQueueDelete(&(predlock->xactLink));
- SHMQueueDelete(&(predlock->targetLink));
+ dlist_delete(&(predlock->xactLink));
+ dlist_delete(&(predlock->targetLink));
hash_search_with_hash_value
(PredicateLockHash,
targettaghash),
HASH_REMOVE, &found);
Assert(found);
-
- predlock = nextpredlock;
}
LWLockRelease(SerializableXactHashLock);
if (oldtarget)
{
PREDICATELOCKTARGET *newtarget;
- PREDICATELOCK *oldpredlock;
PREDICATELOCKTAG newpredlocktag;
+ dlist_mutable_iter iter;
newtarget = hash_search_with_hash_value(PredicateLockTargetHash,
&newtargettag,
/* If we created a new entry, initialize it */
if (!found)
- SHMQueueInit(&(newtarget->predicateLocks));
+ dlist_init(&newtarget->predicateLocks);
newpredlocktag.myTarget = newtarget;
* Loop through all the locks on the old target, replacing them with
* locks on the new target.
*/
- oldpredlock = (PREDICATELOCK *)
- SHMQueueNext(&(oldtarget->predicateLocks),
- &(oldtarget->predicateLocks),
- offsetof(PREDICATELOCK, targetLink));
LWLockAcquire(SerializableXactHashLock, LW_EXCLUSIVE);
- while (oldpredlock)
+
+ dlist_foreach_modify(iter, &oldtarget->predicateLocks)
{
- SHM_QUEUE *predlocktargetlink;
- PREDICATELOCK *nextpredlock;
+ PREDICATELOCK *oldpredlock =
+ dlist_container(PREDICATELOCK, targetLink, iter.cur);
PREDICATELOCK *newpredlock;
SerCommitSeqNo oldCommitSeqNo = oldpredlock->commitSeqNo;
- predlocktargetlink = &(oldpredlock->targetLink);
- nextpredlock = (PREDICATELOCK *)
- SHMQueueNext(&(oldtarget->predicateLocks),
- predlocktargetlink,
- offsetof(PREDICATELOCK, targetLink));
newpredlocktag.myXact = oldpredlock->tag.myXact;
if (removeOld)
{
- SHMQueueDelete(&(oldpredlock->xactLink));
- SHMQueueDelete(&(oldpredlock->targetLink));
+ dlist_delete(&(oldpredlock->xactLink));
+ dlist_delete(&(oldpredlock->targetLink));
hash_search_with_hash_value
(PredicateLockHash,
}
if (!found)
{
- SHMQueueInsertBefore(&(newtarget->predicateLocks),
- &(newpredlock->targetLink));
- SHMQueueInsertBefore(&(newpredlocktag.myXact->predicateLocks),
- &(newpredlock->xactLink));
+ dlist_push_tail(&(newtarget->predicateLocks),
+ &(newpredlock->targetLink));
+ dlist_push_tail(&(newpredlocktag.myXact->predicateLocks),
+ &(newpredlock->xactLink));
newpredlock->commitSeqNo = oldCommitSeqNo;
}
else
Assert(newpredlock->commitSeqNo != 0);
Assert((newpredlock->commitSeqNo == InvalidSerCommitSeqNo)
|| (newpredlock->tag.myXact == OldCommittedSxact));
-
- oldpredlock = nextpredlock;
}
LWLockRelease(SerializableXactHashLock);
if (removeOld)
{
- Assert(SHMQueueEmpty(&oldtarget->predicateLocks));
+ Assert(dlist_is_empty(&oldtarget->predicateLocks));
RemoveTargetIfNoLongerUsed(oldtarget, oldtargettaghash);
}
}
while ((oldtarget = (PREDICATELOCKTARGET *) hash_seq_search(&seqstat)))
{
- PREDICATELOCK *oldpredlock;
+ dlist_mutable_iter iter;
/*
* Check whether this is a target which needs attention.
heaptargettaghash,
HASH_ENTER, &found);
if (!found)
- SHMQueueInit(&heaptarget->predicateLocks);
+ dlist_init(&heaptarget->predicateLocks);
}
/*
* Loop through all the locks on the old target, replacing them with
* locks on the new target.
*/
- oldpredlock = (PREDICATELOCK *)
- SHMQueueNext(&(oldtarget->predicateLocks),
- &(oldtarget->predicateLocks),
- offsetof(PREDICATELOCK, targetLink));
- while (oldpredlock)
+ dlist_foreach_modify(iter, &oldtarget->predicateLocks)
{
- PREDICATELOCK *nextpredlock;
+ PREDICATELOCK *oldpredlock =
+ dlist_container(PREDICATELOCK, targetLink, iter.cur);
PREDICATELOCK *newpredlock;
SerCommitSeqNo oldCommitSeqNo;
SERIALIZABLEXACT *oldXact;
- nextpredlock = (PREDICATELOCK *)
- SHMQueueNext(&(oldtarget->predicateLocks),
- &(oldpredlock->targetLink),
- offsetof(PREDICATELOCK, targetLink));
-
/*
* Remove the old lock first. This avoids the chance of running
* out of lock structure entries for the hash table.
oldCommitSeqNo = oldpredlock->commitSeqNo;
oldXact = oldpredlock->tag.myXact;
- SHMQueueDelete(&(oldpredlock->xactLink));
+ dlist_delete(&(oldpredlock->xactLink));
/*
* No need for retail delete from oldtarget list, we're removing
&found);
if (!found)
{
- SHMQueueInsertBefore(&(heaptarget->predicateLocks),
- &(newpredlock->targetLink));
- SHMQueueInsertBefore(&(newpredlocktag.myXact->predicateLocks),
- &(newpredlock->xactLink));
+ dlist_push_tail(&(heaptarget->predicateLocks),
+ &(newpredlock->targetLink));
+ dlist_push_tail(&(newpredlocktag.myXact->predicateLocks),
+ &(newpredlock->xactLink));
newpredlock->commitSeqNo = oldCommitSeqNo;
}
else
Assert((newpredlock->commitSeqNo == InvalidSerCommitSeqNo)
|| (newpredlock->tag.myXact == OldCommittedSxact));
}
-
- oldpredlock = nextpredlock;
}
hash_search(PredicateLockTargetHash, &oldtarget->tag, HASH_REMOVE,
static void
SetNewSxactGlobalXmin(void)
{
- SERIALIZABLEXACT *sxact;
+ dlist_iter iter;
Assert(LWLockHeldByMe(SerializableXactHashLock));
PredXact->SxactGlobalXmin = InvalidTransactionId;
PredXact->SxactGlobalXminCount = 0;
- for (sxact = FirstPredXact(); sxact != NULL; sxact = NextPredXact(sxact))
+ dlist_foreach(iter, &PredXact->activeList)
{
+ SERIALIZABLEXACT *sxact =
+ dlist_container(SERIALIZABLEXACT, xactLink, iter.cur);
+
if (!SxactIsRolledBack(sxact)
&& !SxactIsCommitted(sxact)
&& sxact != OldCommittedSxact)
ReleasePredicateLocks(bool isCommit, bool isReadOnlySafe)
{
bool needToClear;
- RWConflict conflict,
- nextConflict,
- possibleUnsafeConflict;
SERIALIZABLEXACT *roXact;
+ dlist_mutable_iter iter;
/*
* We can't trust XactReadOnly here, because a transaction which started
* make us unsafe. Note that we use 'inLink' for the iteration as
* opposed to 'outLink' for the r/w xacts.
*/
- possibleUnsafeConflict = (RWConflict)
- SHMQueueNext(&MySerializableXact->possibleUnsafeConflicts,
- &MySerializableXact->possibleUnsafeConflicts,
- offsetof(RWConflictData, inLink));
- while (possibleUnsafeConflict)
+ dlist_foreach_modify(iter, &MySerializableXact->possibleUnsafeConflicts)
{
- nextConflict = (RWConflict)
- SHMQueueNext(&MySerializableXact->possibleUnsafeConflicts,
- &possibleUnsafeConflict->inLink,
- offsetof(RWConflictData, inLink));
+ RWConflict possibleUnsafeConflict =
+ dlist_container(RWConflictData, inLink, iter.cur);
Assert(!SxactIsReadOnly(possibleUnsafeConflict->sxactOut));
Assert(MySerializableXact == possibleUnsafeConflict->sxactIn);
ReleaseRWConflict(possibleUnsafeConflict);
-
- possibleUnsafeConflict = nextConflict;
}
}
* back clear them all. Set SXACT_FLAG_CONFLICT_OUT if any point to
* previously committed transactions.
*/
- conflict = (RWConflict)
- SHMQueueNext(&MySerializableXact->outConflicts,
- &MySerializableXact->outConflicts,
- offsetof(RWConflictData, outLink));
- while (conflict)
+ dlist_foreach_modify(iter, &MySerializableXact->outConflicts)
{
- nextConflict = (RWConflict)
- SHMQueueNext(&MySerializableXact->outConflicts,
- &conflict->outLink,
- offsetof(RWConflictData, outLink));
+ RWConflict conflict =
+ dlist_container(RWConflictData, outLink, iter.cur);
if (isCommit
&& !SxactIsReadOnly(MySerializableXact)
|| SxactIsCommitted(conflict->sxactIn)
|| (conflict->sxactIn->SeqNo.lastCommitBeforeSnapshot >= PredXact->LastSxactCommitSeqNo))
ReleaseRWConflict(conflict);
-
- conflict = nextConflict;
}
/*
* Release all inConflicts from committed and read-only transactions. If
* we're rolling back, clear them all.
*/
- conflict = (RWConflict)
- SHMQueueNext(&MySerializableXact->inConflicts,
- &MySerializableXact->inConflicts,
- offsetof(RWConflictData, inLink));
- while (conflict)
+ dlist_foreach_modify(iter, &MySerializableXact->inConflicts)
{
- nextConflict = (RWConflict)
- SHMQueueNext(&MySerializableXact->inConflicts,
- &conflict->inLink,
- offsetof(RWConflictData, inLink));
+ RWConflict conflict =
+ dlist_container(RWConflictData, inLink, iter.cur);
if (!isCommit
|| SxactIsCommitted(conflict->sxactOut)
|| SxactIsReadOnly(conflict->sxactOut))
ReleaseRWConflict(conflict);
-
- conflict = nextConflict;
}
if (!topLevelIsDeclaredReadOnly)
* conflict out. If any are waiting DEFERRABLE transactions, wake them
* up if they are known safe or known unsafe.
*/
- possibleUnsafeConflict = (RWConflict)
- SHMQueueNext(&MySerializableXact->possibleUnsafeConflicts,
- &MySerializableXact->possibleUnsafeConflicts,
- offsetof(RWConflictData, outLink));
- while (possibleUnsafeConflict)
+ dlist_foreach_modify(iter, &MySerializableXact->possibleUnsafeConflicts)
{
- nextConflict = (RWConflict)
- SHMQueueNext(&MySerializableXact->possibleUnsafeConflicts,
- &possibleUnsafeConflict->outLink,
- offsetof(RWConflictData, outLink));
+ RWConflict possibleUnsafeConflict =
+ dlist_container(RWConflictData, outLink, iter.cur);
roXact = possibleUnsafeConflict->sxactIn;
Assert(MySerializableXact == possibleUnsafeConflict->sxactOut);
* transaction can now safely release its predicate locks (but
* that transaction's backend has to do that itself).
*/
- if (SHMQueueEmpty(&roXact->possibleUnsafeConflicts))
+ if (dlist_is_empty(&roXact->possibleUnsafeConflicts))
roXact->flags |= SXACT_FLAG_RO_SAFE;
}
if (SxactIsDeferrableWaiting(roXact) &&
(SxactIsROUnsafe(roXact) || SxactIsROSafe(roXact)))
ProcSendSignal(roXact->pgprocno);
-
- possibleUnsafeConflict = nextConflict;
}
}
/* Add this to the list of transactions to check for later cleanup. */
if (isCommit)
- SHMQueueInsertBefore(FinishedSerializableTransactions,
- &MySerializableXact->finishedLink);
+ dlist_push_tail(FinishedSerializableTransactions,
+ &MySerializableXact->finishedLink);
/*
* If we're releasing a RO_SAFE transaction in parallel mode, we'll only
static void
ClearOldPredicateLocks(void)
{
- SERIALIZABLEXACT *finishedSxact;
- PREDICATELOCK *predlock;
+ dlist_mutable_iter iter;
/*
* Loop through finished transactions. They are in commit order, so we can
* stop as soon as we find one that's still interesting.
*/
LWLockAcquire(SerializableFinishedListLock, LW_EXCLUSIVE);
- finishedSxact = (SERIALIZABLEXACT *)
- SHMQueueNext(FinishedSerializableTransactions,
- FinishedSerializableTransactions,
- offsetof(SERIALIZABLEXACT, finishedLink));
LWLockAcquire(SerializableXactHashLock, LW_SHARED);
- while (finishedSxact)
+ dlist_foreach_modify(iter, FinishedSerializableTransactions)
{
- SERIALIZABLEXACT *nextSxact;
+ SERIALIZABLEXACT *finishedSxact =
+ dlist_container(SERIALIZABLEXACT, finishedLink, iter.cur);
- nextSxact = (SERIALIZABLEXACT *)
- SHMQueueNext(FinishedSerializableTransactions,
- &(finishedSxact->finishedLink),
- offsetof(SERIALIZABLEXACT, finishedLink));
if (!TransactionIdIsValid(PredXact->SxactGlobalXmin)
|| TransactionIdPrecedesOrEquals(finishedSxact->finishedBefore,
PredXact->SxactGlobalXmin))
* took its snapshot. It's no longer interesting.
*/
LWLockRelease(SerializableXactHashLock);
- SHMQueueDelete(&(finishedSxact->finishedLink));
+ dlist_delete_thoroughly(&finishedSxact->finishedLink);
ReleaseOneSerializableXact(finishedSxact, false, false);
LWLockAcquire(SerializableXactHashLock, LW_SHARED);
}
if (SxactIsReadOnly(finishedSxact))
{
/* A read-only transaction can be removed entirely */
- SHMQueueDelete(&(finishedSxact->finishedLink));
+ dlist_delete_thoroughly(&(finishedSxact->finishedLink));
ReleaseOneSerializableXact(finishedSxact, false, false);
}
else
/* Still interesting. */
break;
}
- finishedSxact = nextSxact;
}
LWLockRelease(SerializableXactHashLock);
* Loop through predicate locks on dummy transaction for summarized data.
*/
LWLockAcquire(SerializablePredicateListLock, LW_SHARED);
- predlock = (PREDICATELOCK *)
- SHMQueueNext(&OldCommittedSxact->predicateLocks,
- &OldCommittedSxact->predicateLocks,
- offsetof(PREDICATELOCK, xactLink));
- while (predlock)
+ dlist_foreach_modify(iter, &OldCommittedSxact->predicateLocks)
{
- PREDICATELOCK *nextpredlock;
+ PREDICATELOCK *predlock =
+ dlist_container(PREDICATELOCK, xactLink, iter.cur);
bool canDoPartialCleanup;
- nextpredlock = (PREDICATELOCK *)
- SHMQueueNext(&OldCommittedSxact->predicateLocks,
- &predlock->xactLink,
- offsetof(PREDICATELOCK, xactLink));
-
LWLockAcquire(SerializableXactHashLock, LW_SHARED);
Assert(predlock->commitSeqNo != 0);
Assert(predlock->commitSeqNo != InvalidSerCommitSeqNo);
LWLockAcquire(partitionLock, LW_EXCLUSIVE);
- SHMQueueDelete(&(predlock->targetLink));
- SHMQueueDelete(&(predlock->xactLink));
+ dlist_delete(&(predlock->targetLink));
+ dlist_delete(&(predlock->xactLink));
hash_search_with_hash_value(PredicateLockHash, &tag,
PredicateLockHashCodeFromTargetHashCode(&tag,
LWLockRelease(partitionLock);
}
-
- predlock = nextpredlock;
}
LWLockRelease(SerializablePredicateListLock);
ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact, bool partial,
bool summarize)
{
- PREDICATELOCK *predlock;
SERIALIZABLEXIDTAG sxidtag;
- RWConflict conflict,
- nextConflict;
+ dlist_mutable_iter iter;
Assert(sxact != NULL);
Assert(SxactIsRolledBack(sxact) || SxactIsCommitted(sxact));
LWLockAcquire(SerializablePredicateListLock, LW_SHARED);
if (IsInParallelMode())
LWLockAcquire(&sxact->perXactPredicateListLock, LW_EXCLUSIVE);
- predlock = (PREDICATELOCK *)
- SHMQueueNext(&(sxact->predicateLocks),
- &(sxact->predicateLocks),
- offsetof(PREDICATELOCK, xactLink));
- while (predlock)
+ dlist_foreach_modify(iter, &sxact->predicateLocks)
{
- PREDICATELOCK *nextpredlock;
+ PREDICATELOCK *predlock =
+ dlist_container(PREDICATELOCK, xactLink, iter.cur);
PREDICATELOCKTAG tag;
- SHM_QUEUE *targetLink;
PREDICATELOCKTARGET *target;
PREDICATELOCKTARGETTAG targettag;
uint32 targettaghash;
LWLock *partitionLock;
- nextpredlock = (PREDICATELOCK *)
- SHMQueueNext(&(sxact->predicateLocks),
- &(predlock->xactLink),
- offsetof(PREDICATELOCK, xactLink));
-
tag = predlock->tag;
- targetLink = &(predlock->targetLink);
target = tag.myTarget;
targettag = target->tag;
targettaghash = PredicateLockTargetTagHashCode(&targettag);
LWLockAcquire(partitionLock, LW_EXCLUSIVE);
- SHMQueueDelete(targetLink);
+ dlist_delete(&predlock->targetLink);
hash_search_with_hash_value(PredicateLockHash, &tag,
PredicateLockHashCodeFromTargetHashCode(&tag,
}
else
{
- SHMQueueInsertBefore(&(target->predicateLocks),
- &(predlock->targetLink));
- SHMQueueInsertBefore(&(OldCommittedSxact->predicateLocks),
- &(predlock->xactLink));
+ dlist_push_tail(&target->predicateLocks,
+ &predlock->targetLink);
+ dlist_push_tail(&OldCommittedSxact->predicateLocks,
+ &predlock->xactLink);
predlock->commitSeqNo = sxact->commitSeqNo;
}
}
RemoveTargetIfNoLongerUsed(target, targettaghash);
LWLockRelease(partitionLock);
-
- predlock = nextpredlock;
}
/*
* Rather than retail removal, just re-init the head after we've run
* through the list.
*/
- SHMQueueInit(&sxact->predicateLocks);
+ dlist_init(&sxact->predicateLocks);
if (IsInParallelMode())
LWLockRelease(&sxact->perXactPredicateListLock);
/* Release all outConflicts (unless 'partial' is true) */
if (!partial)
{
- conflict = (RWConflict)
- SHMQueueNext(&sxact->outConflicts,
- &sxact->outConflicts,
- offsetof(RWConflictData, outLink));
- while (conflict)
+ dlist_foreach_modify(iter, &sxact->outConflicts)
{
- nextConflict = (RWConflict)
- SHMQueueNext(&sxact->outConflicts,
- &conflict->outLink,
- offsetof(RWConflictData, outLink));
+ RWConflict conflict =
+ dlist_container(RWConflictData, outLink, iter.cur);
+
if (summarize)
conflict->sxactIn->flags |= SXACT_FLAG_SUMMARY_CONFLICT_IN;
ReleaseRWConflict(conflict);
- conflict = nextConflict;
}
}
/* Release all inConflicts. */
- conflict = (RWConflict)
- SHMQueueNext(&sxact->inConflicts,
- &sxact->inConflicts,
- offsetof(RWConflictData, inLink));
- while (conflict)
+ dlist_foreach_modify(iter, &sxact->inConflicts)
{
- nextConflict = (RWConflict)
- SHMQueueNext(&sxact->inConflicts,
- &conflict->inLink,
- offsetof(RWConflictData, inLink));
+ RWConflict conflict =
+ dlist_container(RWConflictData, inLink, iter.cur);
+
if (summarize)
conflict->sxactOut->flags |= SXACT_FLAG_SUMMARY_CONFLICT_OUT;
ReleaseRWConflict(conflict);
- conflict = nextConflict;
}
/* Finally, get rid of the xid and the record of the transaction itself. */
errhint("The transaction might succeed if retried.")));
if (SxactHasSummaryConflictIn(MySerializableXact)
- || !SHMQueueEmpty(&MySerializableXact->inConflicts))
+ || !dlist_is_empty(&MySerializableXact->inConflicts))
ereport(ERROR,
(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
errmsg("could not serialize access due to read/write dependencies among transactions"),
uint32 targettaghash;
LWLock *partitionLock;
PREDICATELOCKTARGET *target;
- PREDICATELOCK *predlock;
PREDICATELOCK *mypredlock = NULL;
PREDICATELOCKTAG mypredlocktag;
+ dlist_mutable_iter iter;
Assert(MySerializableXact != InvalidSerializableXact);
* Each lock for an overlapping transaction represents a conflict: a
* rw-dependency in to this transaction.
*/
- predlock = (PREDICATELOCK *)
- SHMQueueNext(&(target->predicateLocks),
- &(target->predicateLocks),
- offsetof(PREDICATELOCK, targetLink));
LWLockAcquire(SerializableXactHashLock, LW_SHARED);
- while (predlock)
- {
- SHM_QUEUE *predlocktargetlink;
- PREDICATELOCK *nextpredlock;
- SERIALIZABLEXACT *sxact;
- predlocktargetlink = &(predlock->targetLink);
- nextpredlock = (PREDICATELOCK *)
- SHMQueueNext(&(target->predicateLocks),
- predlocktargetlink,
- offsetof(PREDICATELOCK, targetLink));
+ dlist_foreach_modify(iter, &target->predicateLocks)
+ {
+ PREDICATELOCK *predlock =
+ dlist_container(PREDICATELOCK, targetLink, iter.cur);
+ SERIALIZABLEXACT *sxact = predlock->tag.myXact;
- sxact = predlock->tag.myXact;
if (sxact == MySerializableXact)
{
/*
LWLockRelease(SerializableXactHashLock);
LWLockAcquire(SerializableXactHashLock, LW_SHARED);
}
-
- predlock = nextpredlock;
}
LWLockRelease(SerializableXactHashLock);
LWLockRelease(partitionLock);
{
Assert(rmpredlock == mypredlock);
- SHMQueueDelete(&(mypredlock->targetLink));
- SHMQueueDelete(&(mypredlock->xactLink));
+ dlist_delete(&(mypredlock->targetLink));
+ dlist_delete(&(mypredlock->xactLink));
rmpredlock = (PREDICATELOCK *)
hash_search_with_hash_value(PredicateLockHash,
while ((target = (PREDICATELOCKTARGET *) hash_seq_search(&seqstat)))
{
- PREDICATELOCK *predlock;
+ dlist_mutable_iter iter;
/*
* Check whether this is a target which needs attention.
/*
* Loop through locks for this target and flag conflicts.
*/
- predlock = (PREDICATELOCK *)
- SHMQueueNext(&(target->predicateLocks),
- &(target->predicateLocks),
- offsetof(PREDICATELOCK, targetLink));
- while (predlock)
+ dlist_foreach_modify(iter, &target->predicateLocks)
{
- PREDICATELOCK *nextpredlock;
-
- nextpredlock = (PREDICATELOCK *)
- SHMQueueNext(&(target->predicateLocks),
- &(predlock->targetLink),
- offsetof(PREDICATELOCK, targetLink));
+ PREDICATELOCK *predlock =
+ dlist_container(PREDICATELOCK, targetLink, iter.cur);
if (predlock->tag.myXact != MySerializableXact
&& !RWConflictExists(predlock->tag.myXact, MySerializableXact))
{
FlagRWConflict(predlock->tag.myXact, MySerializableXact);
}
-
- predlock = nextpredlock;
}
}
SERIALIZABLEXACT *writer)
{
bool failure;
- RWConflict conflict;
Assert(LWLockHeldByMe(SerializableXactHashLock));
* to abort.
*------------------------------------------------------------------------
*/
- if (!failure)
+ if (!failure && SxactHasSummaryConflictOut(writer))
+ failure = true;
+ else if (!failure)
{
- if (SxactHasSummaryConflictOut(writer))
- {
- failure = true;
- conflict = NULL;
- }
- else
- conflict = (RWConflict)
- SHMQueueNext(&writer->outConflicts,
- &writer->outConflicts,
- offsetof(RWConflictData, outLink));
- while (conflict)
+ dlist_iter iter;
+
+ dlist_foreach(iter, &writer->outConflicts)
{
+ RWConflict conflict =
+ dlist_container(RWConflictData, outLink, iter.cur);
SERIALIZABLEXACT *t2 = conflict->sxactIn;
if (SxactIsPrepared(t2)
failure = true;
break;
}
- conflict = (RWConflict)
- SHMQueueNext(&writer->outConflicts,
- &conflict->outLink,
- offsetof(RWConflictData, outLink));
}
}
if (SxactHasSummaryConflictIn(reader))
{
failure = true;
- conflict = NULL;
}
else
- conflict = (RWConflict)
- SHMQueueNext(&reader->inConflicts,
- &reader->inConflicts,
- offsetof(RWConflictData, inLink));
- while (conflict)
{
- SERIALIZABLEXACT *t0 = conflict->sxactOut;
+ dlist_iter iter;
- if (!SxactIsDoomed(t0)
- && (!SxactIsCommitted(t0)
- || t0->commitSeqNo >= writer->prepareSeqNo)
- && (!SxactIsReadOnly(t0)
- || t0->SeqNo.lastCommitBeforeSnapshot >= writer->prepareSeqNo))
+ /*
+ * The unconstify is needed as we have no const version of
+ * dlist_foreach().
+ */
+ dlist_foreach(iter, &unconstify(SERIALIZABLEXACT *, reader)->inConflicts)
{
- failure = true;
- break;
+ const RWConflict conflict =
+ dlist_container(RWConflictData, inLink, iter.cur);
+ const SERIALIZABLEXACT *t0 = conflict->sxactOut;
+
+ if (!SxactIsDoomed(t0)
+ && (!SxactIsCommitted(t0)
+ || t0->commitSeqNo >= writer->prepareSeqNo)
+ && (!SxactIsReadOnly(t0)
+ || t0->SeqNo.lastCommitBeforeSnapshot >= writer->prepareSeqNo))
+ {
+ failure = true;
+ break;
+ }
}
- conflict = (RWConflict)
- SHMQueueNext(&reader->inConflicts,
- &conflict->inLink,
- offsetof(RWConflictData, inLink));
}
}
void
PreCommit_CheckForSerializationFailure(void)
{
- RWConflict nearConflict;
+ dlist_iter near_iter;
if (MySerializableXact == InvalidSerializableXact)
return;
errhint("The transaction might succeed if retried.")));
}
- nearConflict = (RWConflict)
- SHMQueueNext(&MySerializableXact->inConflicts,
- &MySerializableXact->inConflicts,
- offsetof(RWConflictData, inLink));
- while (nearConflict)
+ dlist_foreach(near_iter, &MySerializableXact->inConflicts)
{
+ RWConflict nearConflict =
+ dlist_container(RWConflictData, inLink, near_iter.cur);
+
if (!SxactIsCommitted(nearConflict->sxactOut)
&& !SxactIsDoomed(nearConflict->sxactOut))
{
- RWConflict farConflict;
+ dlist_iter far_iter;
- farConflict = (RWConflict)
- SHMQueueNext(&nearConflict->sxactOut->inConflicts,
- &nearConflict->sxactOut->inConflicts,
- offsetof(RWConflictData, inLink));
- while (farConflict)
+ dlist_foreach(far_iter, &nearConflict->sxactOut->inConflicts)
{
+ RWConflict farConflict =
+ dlist_container(RWConflictData, inLink, far_iter.cur);
+
if (farConflict->sxactOut == MySerializableXact
|| (!SxactIsCommitted(farConflict->sxactOut)
&& !SxactIsReadOnly(farConflict->sxactOut)
nearConflict->sxactOut->flags |= SXACT_FLAG_DOOMED;
break;
}
- farConflict = (RWConflict)
- SHMQueueNext(&nearConflict->sxactOut->inConflicts,
- &farConflict->inLink,
- offsetof(RWConflictData, inLink));
}
}
-
- nearConflict = (RWConflict)
- SHMQueueNext(&MySerializableXact->inConflicts,
- &nearConflict->inLink,
- offsetof(RWConflictData, inLink));
}
MySerializableXact->prepareSeqNo = ++(PredXact->LastSxactCommitSeqNo);
void
AtPrepare_PredicateLocks(void)
{
- PREDICATELOCK *predlock;
SERIALIZABLEXACT *sxact;
TwoPhasePredicateRecord record;
TwoPhasePredicateXactRecord *xactRecord;
TwoPhasePredicateLockRecord *lockRecord;
+ dlist_iter iter;
sxact = MySerializableXact;
xactRecord = &(record.data.xactRecord);
*/
Assert(!IsParallelWorker() && !ParallelContextActive());
- predlock = (PREDICATELOCK *)
- SHMQueueNext(&(sxact->predicateLocks),
- &(sxact->predicateLocks),
- offsetof(PREDICATELOCK, xactLink));
-
- while (predlock != NULL)
+ dlist_foreach(iter, &sxact->predicateLocks)
{
+ PREDICATELOCK *predlock =
+ dlist_container(PREDICATELOCK, xactLink, iter.cur);
+
record.type = TWOPHASEPREDICATERECORD_LOCK;
lockRecord->target = predlock->tag.myTarget->tag;
RegisterTwoPhaseRecord(TWOPHASE_RM_PREDICATELOCK_ID, 0,
&record, sizeof(record));
-
- predlock = (PREDICATELOCK *)
- SHMQueueNext(&(sxact->predicateLocks),
- &(predlock->xactLink),
- offsetof(PREDICATELOCK, xactLink));
}
LWLockRelease(SerializablePredicateListLock);
* recovered xact started are still active, except possibly other
* prepared xacts and we don't care whether those are RO_SAFE or not.
*/
- SHMQueueInit(&(sxact->possibleUnsafeConflicts));
+ dlist_init(&(sxact->possibleUnsafeConflicts));
- SHMQueueInit(&(sxact->predicateLocks));
- SHMQueueElemInit(&(sxact->finishedLink));
+ dlist_init(&(sxact->predicateLocks));
+ dlist_node_init(&sxact->finishedLink);
sxact->topXid = xid;
sxact->xmin = xactRecord->xmin;
* we'll conservatively assume that it had both a conflict in and a
* conflict out, and represent that with the summary conflict flags.
*/
- SHMQueueInit(&(sxact->outConflicts));
- SHMQueueInit(&(sxact->inConflicts));
+ dlist_init(&(sxact->outConflicts));
+ dlist_init(&(sxact->inConflicts));
sxact->flags |= SXACT_FLAG_SUMMARY_CONFLICT_IN;
sxact->flags |= SXACT_FLAG_SUMMARY_CONFLICT_OUT;