@@ -108,8 +108,8 @@ intmax_prepared_xacts = 0;
108108
109109typedef struct GlobalTransactionData
110110{
111- GlobalTransaction next ;
112- int pgprocno ;/* dummyproc */
111+ GlobalTransaction next ;/* list link for free list */
112+ int pgprocno ;/*ID of associated dummyPGPROC */
113113BackendId dummyBackendId ;/* similar to backend id for backends */
114114TimestampTz prepared_at ;/* time of preparation */
115115XLogRecPtr prepare_lsn ;/* XLOG offset of prepare record */
@@ -203,10 +203,13 @@ TwoPhaseShmemInit(void)
203203sizeof (GlobalTransaction )* max_prepared_xacts ));
204204for (i = 0 ;i < max_prepared_xacts ;i ++ )
205205{
206- gxacts [ i ]. pgprocno = PreparedXactProcs [ i ]. pgprocno ;
206+ /* insert into linked list */
207207gxacts [i ].next = TwoPhaseState -> freeGXacts ;
208208TwoPhaseState -> 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,
301304errhint ("Increase max_prepared_transactions (currently %d)." ,
302305max_prepared_xacts )));
303306gxact = TwoPhaseState -> freeGXacts ;
304- TwoPhaseState -> freeGXacts = ( GlobalTransaction ) gxact -> next ;
307+ TwoPhaseState -> freeGXacts = gxact -> next ;
305308
306309proc = & ProcGlobal -> allProcs [gxact -> pgprocno ];
307310pgxact = & 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 ;
706694int i ;
707695
708696static 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 */
715703if (xid == cached_xid )
716- return cached_proc ;
704+ return cached_gxact ;
717705
718706LWLockAcquire (TwoPhaseStateLock ,LW_SHARED );
719707
@@ -724,22 +712,50 @@ TwoPhaseGetDummyProc(TransactionId xid)
724712
725713if (pgxact -> xid == xid )
726714{
727- result = & ProcGlobal -> allProcs [ gxact -> pgprocno ] ;
715+ result = gxact ;
728716break ;
729717}
730718}
731719
732720LWLockRelease (TwoPhaseStateLock );
733721
734722if (result == NULL )/* should not happen */
735- elog (ERROR ,"failed to finddummy PGPROC for xid %u" ,xid );
723+ elog (ERROR ,"failed to findGlobalTransaction for xid %u" ,xid );
736724
737725cached_xid = xid ;
738- cached_proc = result ;
726+ cached_gxact = result ;
739727
740728return 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/************************************************************************/