1919 * Portions Copyright (c) 1994, Regents of the University of California
2020 *
2121 * IDENTIFICATION
22- * $PostgreSQL: pgsql/src/backend/utils/time/snapmgr.c,v 1.7 2008/11/25 20:28:29 alvherre Exp $
22+ * $PostgreSQL: pgsql/src/backend/utils/time/snapmgr.c,v 1.8 2008/12/04 14:51:02 alvherre Exp $
2323 *
2424 *-------------------------------------------------------------------------
2525 */
@@ -136,7 +136,8 @@ GetTransactionSnapshot(void)
136136 */
137137 if (IsXactIsoLevelSerializable )
138138 {
139- CurrentSnapshot = RegisterSnapshot (CurrentSnapshot );
139+ CurrentSnapshot = RegisterSnapshotOnOwner (CurrentSnapshot ,
140+ TopTransactionResourceOwner );
140141 registered_serializable = true;
141142 }
142143
@@ -345,14 +346,27 @@ ActiveSnapshotSet(void)
345346
346347/*
347348 * RegisterSnapshot
348- * Register a snapshot as being in use
349+ * Register a snapshot as being in use by the current resource owner
349350 *
350351 * If InvalidSnapshot is passed, it is not registered.
351352 */
352353Snapshot
353354RegisterSnapshot (Snapshot snapshot )
354355{
355- Snapshot snap ;
356+ if (snapshot == InvalidSnapshot )
357+ return InvalidSnapshot ;
358+
359+ return RegisterSnapshotOnOwner (snapshot , CurrentResourceOwner );
360+ }
361+
362+ /*
363+ * RegisterSnapshotOnOwner
364+ * As above, but use the specified resource owner
365+ */
366+ Snapshot
367+ RegisterSnapshotOnOwner (Snapshot snapshot , ResourceOwner owner )
368+ {
369+ Snapshot snap ;
356370
357371 if (snapshot == InvalidSnapshot )
358372 return InvalidSnapshot ;
@@ -361,9 +375,9 @@ RegisterSnapshot(Snapshot snapshot)
361375 snap = snapshot -> copied ? snapshot : CopySnapshot (snapshot );
362376
363377 /* and tell resowner.c about it */
364- ResourceOwnerEnlargeSnapshots (CurrentResourceOwner );
378+ ResourceOwnerEnlargeSnapshots (owner );
365379 snap -> regd_count ++ ;
366- ResourceOwnerRememberSnapshot (CurrentResourceOwner , snap );
380+ ResourceOwnerRememberSnapshot (owner , snap );
367381
368382 RegisteredSnapshots ++ ;
369383
@@ -379,14 +393,27 @@ RegisterSnapshot(Snapshot snapshot)
379393 */
380394void
381395UnregisterSnapshot (Snapshot snapshot )
396+ {
397+ if (snapshot == NULL )
398+ return ;
399+
400+ UnregisterSnapshotFromOwner (snapshot , CurrentResourceOwner );
401+ }
402+
403+ /*
404+ * UnregisterSnapshotFromOwner
405+ * As above, but use the specified resource owner
406+ */
407+ void
408+ UnregisterSnapshotFromOwner (Snapshot snapshot , ResourceOwner owner )
382409{
383410 if (snapshot == NULL )
384411 return ;
385412
386413 Assert (snapshot -> regd_count > 0 );
387414 Assert (RegisteredSnapshots > 0 );
388415
389- ResourceOwnerForgetSnapshot (CurrentResourceOwner , snapshot );
416+ ResourceOwnerForgetSnapshot (owner , snapshot );
390417 RegisteredSnapshots -- ;
391418 if (-- snapshot -> regd_count == 0 && snapshot -> active_count == 0 )
392419 {
@@ -463,6 +490,26 @@ AtSubAbort_Snapshot(int level)
463490 SnapshotResetXmin ();
464491}
465492
493+ /*
494+ * AtEarlyCommit_Snapshot
495+ *
496+ * Snapshot manager's cleanup function, to be called on commit, before
497+ * doing resowner.c resource release.
498+ */
499+ void
500+ AtEarlyCommit_Snapshot (void )
501+ {
502+ /*
503+ * On a serializable transaction we must unregister our private refcount to
504+ * the serializable snapshot.
505+ */
506+ if (registered_serializable )
507+ UnregisterSnapshotFromOwner (CurrentSnapshot ,
508+ TopTransactionResourceOwner );
509+ registered_serializable = false;
510+
511+ }
512+
466513/*
467514 * AtEOXact_Snapshot
468515 * Snapshot manager's cleanup function for end of transaction
@@ -475,13 +522,6 @@ AtEOXact_Snapshot(bool isCommit)
475522 {
476523 ActiveSnapshotElt * active ;
477524
478- /*
479- * On a serializable snapshot we must first unregister our private
480- * refcount to the serializable snapshot.
481- */
482- if (registered_serializable )
483- UnregisterSnapshot (CurrentSnapshot );
484-
485525 if (RegisteredSnapshots != 0 )
486526 elog (WARNING , "%d registered snapshots seem to remain after cleanup" ,
487527 RegisteredSnapshots );
0 commit comments