@@ -120,7 +120,7 @@ static void GetMultiXactIdHintBits(MultiXactId multi, uint16 *new_infomask,
120120static TransactionId MultiXactIdGetUpdateXid (TransactionId xmax ,
121121uint16 t_infomask );
122122static bool DoesMultiXactIdConflict (MultiXactId multi ,uint16 infomask ,
123- LockTupleMode lockmode , bool * current_is_member );
123+ LockTupleMode lockmode );
124124static void MultiXactIdWait (MultiXactId multi ,MultiXactStatus status ,uint16 infomask ,
125125Relation rel ,ItemPointer ctid ,XLTW_Oper oper ,
126126int * remaining );
@@ -3161,20 +3161,15 @@ heap_delete(Relation relation, ItemPointer tid,
31613161 */
31623162if (infomask & HEAP_XMAX_IS_MULTI )
31633163{
3164- bool current_is_member = false;
3165-
3164+ /* wait for multixact */
31663165if (DoesMultiXactIdConflict ((MultiXactId )xwait ,infomask ,
3167- LockTupleExclusive , & current_is_member ))
3166+ LockTupleExclusive ))
31683167{
31693168LockBuffer (buffer ,BUFFER_LOCK_UNLOCK );
31703169
3171- /*
3172- * Acquire the lock, if necessary (but skip it when we're
3173- * requesting a lock and already have one; avoids deadlock).
3174- */
3175- if (!current_is_member )
3176- heap_acquire_tuplock (relation ,& (tp .t_self ),LockTupleExclusive ,
3177- LockWaitBlock ,& have_tuple_lock );
3170+ /* acquire tuple lock, if necessary */
3171+ heap_acquire_tuplock (relation ,& (tp .t_self ),LockTupleExclusive ,
3172+ LockWaitBlock ,& have_tuple_lock );
31783173
31793174/* wait for multixact */
31803175MultiXactIdWait ((MultiXactId )xwait ,MultiXactStatusUpdate ,infomask ,
@@ -3773,20 +3768,15 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
37733768{
37743769TransactionId update_xact ;
37753770int remain ;
3776- bool current_is_member = false;
37773771
37783772if (DoesMultiXactIdConflict ((MultiXactId )xwait ,infomask ,
3779- * lockmode , & current_is_member ))
3773+ * lockmode ))
37803774{
37813775LockBuffer (buffer ,BUFFER_LOCK_UNLOCK );
37823776
3783- /*
3784- * Acquire the lock, if necessary (but skip it when we're
3785- * requesting a lock and already have one; avoids deadlock).
3786- */
3787- if (!current_is_member )
3788- heap_acquire_tuplock (relation ,& (oldtup .t_self ),* lockmode ,
3789- LockWaitBlock ,& have_tuple_lock );
3777+ /* acquire tuple lock, if necessary */
3778+ heap_acquire_tuplock (relation ,& (oldtup .t_self ),* lockmode ,
3779+ LockWaitBlock ,& have_tuple_lock );
37903780
37913781/* wait for multixact */
37923782MultiXactIdWait ((MultiXactId )xwait ,mxact_status ,infomask ,
@@ -4756,7 +4746,6 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
47564746uint16 infomask ;
47574747uint16 infomask2 ;
47584748bool require_sleep ;
4759- bool skip_tuple_lock = false;
47604749ItemPointerData t_ctid ;
47614750
47624751/* must copy state data before unlocking buffer */
@@ -4810,21 +4799,6 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
48104799result = HeapTupleMayBeUpdated ;
48114800gotoout_unlocked ;
48124801}
4813- else
4814- {
4815- /*
4816- * Disable acquisition of the heavyweight tuple lock.
4817- * Otherwise, when promoting a weaker lock, we might
4818- * deadlock with another locker that has acquired the
4819- * heavyweight tuple lock and is waiting for our
4820- * transaction to finish.
4821- *
4822- * Note that in this case we still need to wait for
4823- * the multixact if required, to avoid acquiring
4824- * conflicting locks.
4825- */
4826- skip_tuple_lock = true;
4827- }
48284802}
48294803
48304804if (members )
@@ -4979,7 +4953,7 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
49794953if (infomask & HEAP_XMAX_IS_MULTI )
49804954{
49814955if (!DoesMultiXactIdConflict ((MultiXactId )xwait ,infomask ,
4982- mode , NULL ))
4956+ mode ))
49834957{
49844958/*
49854959 * No conflict, but if the xmax changed under us in the
@@ -5056,15 +5030,13 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
50565030/*
50575031 * Acquire tuple lock to establish our priority for the tuple, or
50585032 * die trying. LockTuple will release us when we are next-in-line
5059- * for the tuple. We must do this even if we are share-locking,
5060- * but not if we already have a weaker lock on the tuple.
5033+ * for the tuple. We must do this even if we are share-locking.
50615034 *
50625035 * If we are forced to "start over" below, we keep the tuple lock;
50635036 * this arranges that we stay at the head of the line while
50645037 * rechecking tuple state.
50655038 */
5066- if (!skip_tuple_lock &&
5067- !heap_acquire_tuplock (relation ,tid ,mode ,wait_policy ,
5039+ if (!heap_acquire_tuplock (relation ,tid ,mode ,wait_policy ,
50685040& have_tuple_lock ))
50695041{
50705042/*
@@ -7242,13 +7214,10 @@ HeapTupleGetUpdateXid(HeapTupleHeader tuple)
72427214 * tuple lock of the given strength?
72437215 *
72447216 * The passed infomask pairs up with the given multixact in the tuple header.
7245- *
7246- * If current_is_member is not NULL, it is set to 'true' if the current
7247- * transaction is a member of the given multixact.
72487217 */
72497218static bool
72507219DoesMultiXactIdConflict (MultiXactId multi ,uint16 infomask ,
7251- LockTupleMode lockmode , bool * current_is_member )
7220+ LockTupleMode lockmode )
72527221{
72537222int nmembers ;
72547223MultiXactMember * members ;
@@ -7269,26 +7238,17 @@ DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask,
72697238TransactionId memxid ;
72707239LOCKMODE memlockmode ;
72717240
7272- if (result && (current_is_member == NULL || * current_is_member ))
7273- break ;
7274-
72757241memlockmode = LOCKMODE_from_mxstatus (members [i ].status );
72767242
7277- /* ignore members from current xact (but track their presence) */
7278- memxid = members [i ].xid ;
7279- if (TransactionIdIsCurrentTransactionId (memxid ))
7280- {
7281- if (current_is_member != NULL )
7282- * current_is_member = true;
7283- continue ;
7284- }
7285- else if (result )
7286- continue ;
7287-
72887243/* ignore members that don't conflict with the lock we want */
72897244if (!DoLockModesConflict (memlockmode ,wanted ))
72907245continue ;
72917246
7247+ /* ignore members from current xact */
7248+ memxid = members [i ].xid ;
7249+ if (TransactionIdIsCurrentTransactionId (memxid ))
7250+ continue ;
7251+
72927252if (ISUPDATE_from_mxstatus (members [i ].status ))
72937253{
72947254/* ignore aborted updaters */
@@ -7305,11 +7265,10 @@ DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask,
73057265/*
73067266 * Whatever remains are either live lockers that conflict with our
73077267 * wanted lock, and updaters that are not aborted. Those conflict
7308- * with what we want. Set up to return true, but keep going to
7309- * look for the current transaction among the multixact members,
7310- * if needed.
7268+ * with what we want, so return true.
73117269 */
73127270result = true;
7271+ break ;
73137272}
73147273pfree (members );
73157274}