@@ -108,8 +108,8 @@ int max_prepared_xacts = 0;
108108
109109typedef struct GlobalTransactionData
110110{
111- GlobalTransaction next ;
112- int pgprocno ; /* dummy proc */
111+ GlobalTransaction next ; /* list link for free list */
112+ int pgprocno ; /* ID of associated dummy PGPROC */
113113 BackendId dummyBackendId ; /* similar to backend id for backends */
114114 TimestampTz prepared_at ; /* time of preparation */
115115 XLogRecPtr prepare_lsn ; /* XLOG offset of prepare record */
@@ -203,10 +203,13 @@ TwoPhaseShmemInit(void)
203203 sizeof (GlobalTransaction ) * max_prepared_xacts ));
204204 for (i = 0 ; i < max_prepared_xacts ; i ++ )
205205 {
206- gxacts [ i ]. pgprocno = PreparedXactProcs [ i ]. pgprocno ;
206+ /* insert into linked list */
207207 gxacts [i ].next = TwoPhaseState -> freeGXacts ;
208208 TwoPhaseState -> freeGXacts = & gxacts [i ];
209209
210+ /* associate it with a PGPROC assigned by InitProcGlobal */
211+ gxacts [i ].pgprocno = PreparedXactProcs [i ].pgprocno ;
212+
210213 /*
211214 * Assign a unique ID for each dummy proc, so that the range of
212215 * dummy backend IDs immediately follows the range of normal
@@ -301,7 +304,7 @@ MarkAsPreparing(TransactionId xid, const char *gid,
301304 errhint ("Increase max_prepared_transactions (currently %d)." ,
302305 max_prepared_xacts )));
303306 gxact = TwoPhaseState -> freeGXacts ;
304- TwoPhaseState -> freeGXacts = ( GlobalTransaction ) gxact -> next ;
307+ TwoPhaseState -> freeGXacts = gxact -> next ;
305308
306309 proc = & ProcGlobal -> allProcs [gxact -> pgprocno ];
307310 pgxact = & ProcGlobal -> allPgXact [gxact -> pgprocno ];
@@ -680,40 +683,25 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
680683}
681684
682685/*
683- * TwoPhaseGetDummyProc
684- * Get the dummy backend ID for prepared transaction specified by XID
685- *
686- * Dummy backend IDs are similar to real backend IDs of real backends.
687- * They start at MaxBackends + 1, and are unique across all currently active
688- * real backends and prepared transactions.
686+ * TwoPhaseGetGXact
687+ * Get the GlobalTransaction struct for a prepared transaction
688+ * specified by XID
689689 */
690- BackendId
691- TwoPhaseGetDummyBackendId (TransactionId xid )
692- {
693- PGPROC * proc = TwoPhaseGetDummyProc (xid );
694-
695- return ((GlobalTransaction ) proc )-> dummyBackendId ;
696- }
697-
698- /*
699- * TwoPhaseGetDummyProc
700- * Get the PGPROC that represents a prepared transaction specified by XID
701- */
702- PGPROC *
703- TwoPhaseGetDummyProc (TransactionId xid )
690+ static GlobalTransaction
691+ TwoPhaseGetGXact (TransactionId xid )
704692{
705- PGPROC * result = NULL ;
693+ GlobalTransaction result = NULL ;
706694 int i ;
707695
708696 static TransactionId cached_xid = InvalidTransactionId ;
709- static PGPROC * cached_proc = NULL ;
697+ static GlobalTransaction cached_gxact = NULL ;
710698
711699 /*
712700 * During a recovery, COMMIT PREPARED, or ABORT PREPARED, we'll be called
713701 * repeatedly for the same XID. We can save work with a simple cache.
714702 */
715703 if (xid == cached_xid )
716- return cached_proc ;
704+ return cached_gxact ;
717705
718706 LWLockAcquire (TwoPhaseStateLock , LW_SHARED );
719707
@@ -724,22 +712,50 @@ TwoPhaseGetDummyProc(TransactionId xid)
724712
725713 if (pgxact -> xid == xid )
726714 {
727- result = & ProcGlobal -> allProcs [ gxact -> pgprocno ] ;
715+ result = gxact ;
728716 break ;
729717 }
730718 }
731719
732720 LWLockRelease (TwoPhaseStateLock );
733721
734722 if (result == NULL ) /* should not happen */
735- elog (ERROR , "failed to find dummy PGPROC for xid %u" , xid );
723+ elog (ERROR , "failed to find GlobalTransaction for xid %u" , xid );
736724
737725 cached_xid = xid ;
738- cached_proc = result ;
726+ cached_gxact = result ;
739727
740728 return result ;
741729}
742730
731+ /*
732+ * TwoPhaseGetDummyProc
733+ * Get the dummy backend ID for prepared transaction specified by XID
734+ *
735+ * Dummy backend IDs are similar to real backend IDs of real backends.
736+ * They start at MaxBackends + 1, and are unique across all currently active
737+ * real backends and prepared transactions.
738+ */
739+ BackendId
740+ TwoPhaseGetDummyBackendId (TransactionId xid )
741+ {
742+ GlobalTransaction gxact = TwoPhaseGetGXact (xid );
743+
744+ return gxact -> dummyBackendId ;
745+ }
746+
747+ /*
748+ * TwoPhaseGetDummyProc
749+ * Get the PGPROC that represents a prepared transaction specified by XID
750+ */
751+ PGPROC *
752+ TwoPhaseGetDummyProc (TransactionId xid )
753+ {
754+ GlobalTransaction gxact = TwoPhaseGetGXact (xid );
755+
756+ return & ProcGlobal -> allProcs [gxact -> pgprocno ];
757+ }
758+
743759/************************************************************************/
744760/* State file support */
745761/************************************************************************/
0 commit comments