@@ -115,7 +115,7 @@ static void GetMultiXactIdHintBits(MultiXactId multi, uint16 *new_infomask,
115
115
static TransactionId MultiXactIdGetUpdateXid (TransactionId xmax ,
116
116
uint16 t_infomask );
117
117
static bool DoesMultiXactIdConflict (MultiXactId multi ,uint16 infomask ,
118
- LockTupleMode lockmode , bool * current_is_member );
118
+ LockTupleMode lockmode );
119
119
static void MultiXactIdWait (MultiXactId multi ,MultiXactStatus status ,uint16 infomask ,
120
120
Relation rel ,ItemPointer ctid ,XLTW_Oper oper ,
121
121
int * remaining );
@@ -3112,20 +3112,15 @@ heap_delete(Relation relation, ItemPointer tid,
3112
3112
*/
3113
3113
if (infomask & HEAP_XMAX_IS_MULTI )
3114
3114
{
3115
- bool current_is_member = false;
3116
-
3115
+ /* wait for multixact */
3117
3116
if (DoesMultiXactIdConflict ((MultiXactId )xwait ,infomask ,
3118
- LockTupleExclusive , & current_is_member ))
3117
+ LockTupleExclusive ))
3119
3118
{
3120
3119
LockBuffer (buffer ,BUFFER_LOCK_UNLOCK );
3121
3120
3122
- /*
3123
- * Acquire the lock, if necessary (but skip it when we're
3124
- * requesting a lock and already have one; avoids deadlock).
3125
- */
3126
- if (!current_is_member )
3127
- heap_acquire_tuplock (relation ,& (tp .t_self ),LockTupleExclusive ,
3128
- LockWaitBlock ,& have_tuple_lock );
3121
+ /* acquire tuple lock, if necessary */
3122
+ heap_acquire_tuplock (relation ,& (tp .t_self ),LockTupleExclusive ,
3123
+ LockWaitBlock ,& have_tuple_lock );
3129
3124
3130
3125
/* wait for multixact */
3131
3126
MultiXactIdWait ((MultiXactId )xwait ,MultiXactStatusUpdate ,infomask ,
@@ -3715,20 +3710,15 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
3715
3710
{
3716
3711
TransactionId update_xact ;
3717
3712
int remain ;
3718
- bool current_is_member = false;
3719
3713
3720
3714
if (DoesMultiXactIdConflict ((MultiXactId )xwait ,infomask ,
3721
- * lockmode , & current_is_member ))
3715
+ * lockmode ))
3722
3716
{
3723
3717
LockBuffer (buffer ,BUFFER_LOCK_UNLOCK );
3724
3718
3725
- /*
3726
- * Acquire the lock, if necessary (but skip it when we're
3727
- * requesting a lock and already have one; avoids deadlock).
3728
- */
3729
- if (!current_is_member )
3730
- heap_acquire_tuplock (relation ,& (oldtup .t_self ),* lockmode ,
3731
- LockWaitBlock ,& have_tuple_lock );
3719
+ /* acquire tuple lock, if necessary */
3720
+ heap_acquire_tuplock (relation ,& (oldtup .t_self ),* lockmode ,
3721
+ LockWaitBlock ,& have_tuple_lock );
3732
3722
3733
3723
/* wait for multixact */
3734
3724
MultiXactIdWait ((MultiXactId )xwait ,mxact_status ,infomask ,
@@ -4610,7 +4600,6 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
4610
4600
uint16 infomask ;
4611
4601
uint16 infomask2 ;
4612
4602
bool require_sleep ;
4613
- bool skip_tuple_lock = false;
4614
4603
ItemPointerData t_ctid ;
4615
4604
4616
4605
/* must copy state data before unlocking buffer */
@@ -4664,21 +4653,6 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
4664
4653
result = HeapTupleMayBeUpdated ;
4665
4654
gotoout_unlocked ;
4666
4655
}
4667
- else
4668
- {
4669
- /*
4670
- * Disable acquisition of the heavyweight tuple lock.
4671
- * Otherwise, when promoting a weaker lock, we might
4672
- * deadlock with another locker that has acquired the
4673
- * heavyweight tuple lock and is waiting for our
4674
- * transaction to finish.
4675
- *
4676
- * Note that in this case we still need to wait for
4677
- * the multixact if required, to avoid acquiring
4678
- * conflicting locks.
4679
- */
4680
- skip_tuple_lock = true;
4681
- }
4682
4656
}
4683
4657
4684
4658
if (members )
@@ -4833,7 +4807,7 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
4833
4807
if (infomask & HEAP_XMAX_IS_MULTI )
4834
4808
{
4835
4809
if (!DoesMultiXactIdConflict ((MultiXactId )xwait ,infomask ,
4836
- mode , NULL ))
4810
+ mode ))
4837
4811
{
4838
4812
/*
4839
4813
* No conflict, but if the xmax changed under us in the
@@ -4910,15 +4884,13 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
4910
4884
/*
4911
4885
* Acquire tuple lock to establish our priority for the tuple, or
4912
4886
* die trying. LockTuple will release us when we are next-in-line
4913
- * for the tuple. We must do this even if we are share-locking,
4914
- * but not if we already have a weaker lock on the tuple.
4887
+ * for the tuple. We must do this even if we are share-locking.
4915
4888
*
4916
4889
* If we are forced to "start over" below, we keep the tuple lock;
4917
4890
* this arranges that we stay at the head of the line while
4918
4891
* rechecking tuple state.
4919
4892
*/
4920
- if (!skip_tuple_lock &&
4921
- !heap_acquire_tuplock (relation ,tid ,mode ,wait_policy ,
4893
+ if (!heap_acquire_tuplock (relation ,tid ,mode ,wait_policy ,
4922
4894
& have_tuple_lock ))
4923
4895
{
4924
4896
/*
@@ -7090,13 +7062,10 @@ HeapTupleGetUpdateXid(HeapTupleHeader tuple)
7090
7062
* tuple lock of the given strength?
7091
7063
*
7092
7064
* The passed infomask pairs up with the given multixact in the tuple header.
7093
- *
7094
- * If current_is_member is not NULL, it is set to 'true' if the current
7095
- * transaction is a member of the given multixact.
7096
7065
*/
7097
7066
static bool
7098
7067
DoesMultiXactIdConflict (MultiXactId multi ,uint16 infomask ,
7099
- LockTupleMode lockmode , bool * current_is_member )
7068
+ LockTupleMode lockmode )
7100
7069
{
7101
7070
int nmembers ;
7102
7071
MultiXactMember * members ;
@@ -7117,26 +7086,17 @@ DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask,
7117
7086
TransactionId memxid ;
7118
7087
LOCKMODE memlockmode ;
7119
7088
7120
- if (result && (current_is_member == NULL || * current_is_member ))
7121
- break ;
7122
-
7123
7089
memlockmode = LOCKMODE_from_mxstatus (members [i ].status );
7124
7090
7125
- /* ignore members from current xact (but track their presence) */
7126
- memxid = members [i ].xid ;
7127
- if (TransactionIdIsCurrentTransactionId (memxid ))
7128
- {
7129
- if (current_is_member != NULL )
7130
- * current_is_member = true;
7131
- continue ;
7132
- }
7133
- else if (result )
7134
- continue ;
7135
-
7136
7091
/* ignore members that don't conflict with the lock we want */
7137
7092
if (!DoLockModesConflict (memlockmode ,wanted ))
7138
7093
continue ;
7139
7094
7095
+ /* ignore members from current xact */
7096
+ memxid = members [i ].xid ;
7097
+ if (TransactionIdIsCurrentTransactionId (memxid ))
7098
+ continue ;
7099
+
7140
7100
if (ISUPDATE_from_mxstatus (members [i ].status ))
7141
7101
{
7142
7102
/* ignore aborted updaters */
@@ -7153,11 +7113,10 @@ DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask,
7153
7113
/*
7154
7114
* Whatever remains are either live lockers that conflict with our
7155
7115
* wanted lock, and updaters that are not aborted. Those conflict
7156
- * with what we want. Set up to return true, but keep going to
7157
- * look for the current transaction among the multixact members,
7158
- * if needed.
7116
+ * with what we want, so return true.
7159
7117
*/
7160
7118
result = true;
7119
+ break ;
7161
7120
}
7162
7121
pfree (members );
7163
7122
}