I attach a small patch that slightly refactors some code in
storage/smgr/smgr.c.  Regression test pass.  There's no change in
functionality, only code reordering.  (Well, it changes an ad-hoc linked
list into a proper List).

Please review and if Ok, apply.

-- 
Alvaro Herrera (<alvherre[a]dcc.uchile.cl>)
"At least to kernel hackers, who really are human, despite occasional
rumors to the contrary" (LWN.net)
diff -cr --exclude=CVS 01trivial/src/backend/access/transam/xact.c 
02smgr/src/backend/access/transam/xact.c
*** 01trivial/src/backend/access/transam/xact.c 2004-01-15 23:34:42.000000000 -0300
--- 02smgr/src/backend/access/transam/xact.c    2004-01-19 19:37:54.000000000 -0300
***************
*** 865,870 ****
--- 865,875 ----
        DeferredTriggerBeginXact();
  
        /*
+        * Initialize the smgr subsystem
+        */
+       PendingDeletesBeginXact();
+ 
+       /*
         * done with start processing, set current transaction state to "in
         * progress"
         */
diff -cr --exclude=CVS 01trivial/src/backend/storage/smgr/smgr.c 
02smgr/src/backend/storage/smgr/smgr.c
*** 01trivial/src/backend/storage/smgr/smgr.c   2004-01-15 23:33:55.000000000 -0300
--- 02smgr/src/backend/storage/smgr/smgr.c      2004-01-19 19:37:54.000000000 -0300
***************
*** 97,105 ****
   * executed immediately, but is just entered in the list.  When and if
   * the transaction commits, we can delete the physical file.
   *
!  * NOTE: the list is kept in TopMemoryContext to be sure it won't disappear
!  * unbetimes.  It'd probably be OK to keep it in TopTransactionContext,
!  * but I'm being paranoid.
   */
  
  typedef struct PendingRelDelete
--- 97,104 ----
   * executed immediately, but is just entered in the list.  When and if
   * the transaction commits, we can delete the physical file.
   *
!  * NOTE: the list is kept in TopTransactionContext, so the items will
!  * automatically disappear when the transaction ends.
   */
  
  typedef struct PendingRelDelete
***************
*** 108,118 ****
        int16           which;                  /* which storage manager? */
        bool            isTemp;                 /* is it a temporary relation? */
        bool            atCommit;               /* T=delete at commit; F=delete at 
abort */
-       struct PendingRelDelete *next;          /* linked-list link */
  } PendingRelDelete;
  
! static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
  
  
  /*
   *    smgrinit(), smgrshutdown() -- Initialize or shut down all storage
--- 107,118 ----
        int16           which;                  /* which storage manager? */
        bool            isTemp;                 /* is it a temporary relation? */
        bool            atCommit;               /* T=delete at commit; F=delete at 
abort */
  } PendingRelDelete;
  
! static List *pendingDeletes;
  
+ static void smgrDeleteItem(PendingRelDelete *pending);
+ static void addPendingDelete(int16 which, Relation reln, bool atCommit);
  
  /*
   *    smgrinit(), smgrshutdown() -- Initialize or shut down all storage
***************
*** 168,174 ****
  smgrcreate(int16 which, Relation reln)
  {
        int                     fd;
-       PendingRelDelete *pending;
  
        if ((fd = (*(smgrsw[which].smgr_create)) (reln)) < 0)
                ereport(ERROR,
--- 168,173 ----
***************
*** 177,190 ****
                                                RelationGetRelationName(reln))));
  
        /* Add the relation to the list of stuff to delete at abort */
!       pending = (PendingRelDelete *)
!               MemoryContextAlloc(TopMemoryContext, sizeof(PendingRelDelete));
!       pending->relnode = reln->rd_node;
!       pending->which = which;
!       pending->isTemp = reln->rd_istemp;
!       pending->atCommit = false;      /* delete if abort */
!       pending->next = pendingDeletes;
!       pendingDeletes = pending;
  
        return fd;
  }
--- 176,182 ----
                                                RelationGetRelationName(reln))));
  
        /* Add the relation to the list of stuff to delete at abort */
!       addPendingDelete(which, reln, false);
  
        return fd;
  }
***************
*** 198,218 ****
  int
  smgrunlink(int16 which, Relation reln)
  {
-       PendingRelDelete *pending;
  
        /* Make sure the file is closed */
        if (reln->rd_fd >= 0)
                smgrclose(which, reln);
  
        /* Add the relation to the list of stuff to delete at commit */
!       pending = (PendingRelDelete *)
!               MemoryContextAlloc(TopMemoryContext, sizeof(PendingRelDelete));
!       pending->relnode = reln->rd_node;
!       pending->which = which;
!       pending->isTemp = reln->rd_istemp;
!       pending->atCommit = true;       /* delete if commit */
!       pending->next = pendingDeletes;
!       pendingDeletes = pending;
  
        /*
         * NOTE: if the relation was created in this transaction, it will now
--- 190,202 ----
  int
  smgrunlink(int16 which, Relation reln)
  {
  
        /* Make sure the file is closed */
        if (reln->rd_fd >= 0)
                smgrclose(which, reln);
  
        /* Add the relation to the list of stuff to delete at commit */
!       addPendingDelete(which, reln, true);
  
        /*
         * NOTE: if the relation was created in this transaction, it will now
***************
*** 444,496 ****
  }
  
  /*
   *    smgrDoPendingDeletes() -- Take care of relation deletes at end of xact.
   */
  int
  smgrDoPendingDeletes(bool isCommit)
  {
!       while (pendingDeletes != NULL)
        {
!               PendingRelDelete *pending = pendingDeletes;
  
-               pendingDeletes = pending->next;
                if (pending->atCommit == isCommit)
!               {
!                       /*
!                        * Get rid of any leftover buffers for the rel (shouldn't be
!                        * any in the commit case, but there can be in the abort
!                        * case).
!                        */
!                       DropRelFileNodeBuffers(pending->relnode, pending->isTemp);
! 
!                       /*
!                        * Tell the free space map to forget this relation.  It won't
!                        * be accessed any more anyway, but we may as well recycle the
!                        * map space quickly.
!                        */
!                       FreeSpaceMapForgetRel(&pending->relnode);
! 
!                       /*
!                        * And delete the physical files.
!                        *
!                        * Note: we treat deletion failure as a WARNING, not an error,
!                        * because we've already decided to commit or abort the
!                        * current xact.
!                        */
!                       if ((*(smgrsw[pending->which].smgr_unlink)) (pending->relnode) 
== SM_FAIL)
!                               ereport(WARNING,
!                                               (errcode_for_file_access(),
!                                                errmsg("could not unlink %u/%u: %m",
!                                                               
pending->relnode.tblNode,
!                                                               
pending->relnode.relNode)));
!               }
!               pfree(pending);
        }
  
        return SM_SUCCESS;
  }
  
  /*
   *    smgrcommit() -- Prepare to commit changes made during the current
   *                                    transaction.
   *
--- 428,519 ----
  }
  
  /*
+  * Add a relation to delete at transaction end.
+  */
+ void
+ addPendingDelete(int16 which, Relation reln, bool atCommit)
+ {
+       MemoryContext old_cxt = MemoryContextSwitchTo(TopTransactionContext);
+       PendingRelDelete *pending = (PendingRelDelete *) 
palloc(sizeof(PendingRelDelete));
+ 
+       pending->relnode = reln->rd_node;
+       pending->which = which;
+       pending->isTemp = reln->rd_istemp;
+       pending->atCommit = atCommit;
+       pendingDeletes = lcons(pending, pendingDeletes);
+ 
+       MemoryContextSwitchTo(old_cxt);
+ }
+ 
+ /*
+  * Delete a pending relation.
+  */
+ void
+ smgrDeleteItem(PendingRelDelete *pending)
+ {
+       /*
+        * Get rid of any leftover buffers for the rel (shouldn't be
+        * any in the commit case, but there can be in the abort
+        * case).
+        */
+       DropRelFileNodeBuffers(pending->relnode, pending->isTemp);
+ 
+       /*
+        * Tell the free space map to forget this relation.  It won't
+        * be accessed any more anyway, but we may as well recycle the
+        * map space quickly.
+        */
+       FreeSpaceMapForgetRel(&pending->relnode);
+ 
+       /*
+        * And delete the physical files.
+        *
+        * Note: we treat deletion failure as a WARNING, not an error,
+        * because we've already decided to commit or abort the
+        * current xact.
+        */
+       if ((*(smgrsw[pending->which].smgr_unlink)) (pending->relnode) == SM_FAIL)
+               ereport(WARNING,
+                               (errcode_for_file_access(),
+                                errmsg("could not unlink %u/%u: %m",
+                                        pending->relnode.tblNode,
+                                        pending->relnode.relNode)));
+ }
+ 
+ /*
   *    smgrDoPendingDeletes() -- Take care of relation deletes at end of xact.
   */
  int
  smgrDoPendingDeletes(bool isCommit)
  {
!       List *p;
!       foreach (p, pendingDeletes)
        {
!               PendingRelDelete *pending = (PendingRelDelete *)lfirst(p);
  
                if (pending->atCommit == isCommit)
!                       smgrDeleteItem(pending);
! 
!               /*
!                * The structs will be freed at the end of the transaction,
!                * no need to free them individually.
!                */
        }
+       pendingDeletes = NIL;
  
        return SM_SUCCESS;
  }
  
  /*
+  * Initializes the smgr pending deletes queue.
+  */
+ void
+ PendingDeletesBeginXact(void)
+ {
+       pendingDeletes = NIL;
+ }
+ 
+ /*
   *    smgrcommit() -- Prepare to commit changes made during the current
   *                                    transaction.
   *
diff -cr --exclude=CVS 01trivial/src/include/storage/smgr.h 
02smgr/src/include/storage/smgr.h
*** 01trivial/src/include/storage/smgr.h        2004-01-15 23:34:12.000000000 -0300
--- 02smgr/src/include/storage/smgr.h   2004-01-19 19:37:54.000000000 -0300
***************
*** 43,48 ****
--- 43,50 ----
  extern BlockNumber smgrtruncate(int16 which, Relation reln,
                         BlockNumber nblocks);
  extern int    smgrDoPendingDeletes(bool isCommit);
+ extern void PendingDeletesBeginXact(void);
+ 
  extern int    smgrcommit(void);
  extern int    smgrabort(void);
  extern int    smgrsync(void);
---------------------------(end of broadcast)---------------------------
TIP 2: you can get off all lists at once with the unregister command
    (send "unregister YourEmailAddressHere" to [EMAIL PROTECTED])

Reply via email to