diff options
Diffstat (limited to 'src/backend/storage/smgr/smgr.c')
-rw-r--r-- | src/backend/storage/smgr/smgr.c | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c index 37be3081803..fcbdc4117a5 100644 --- a/src/backend/storage/smgr/smgr.c +++ b/src/backend/storage/smgr/smgr.c @@ -84,6 +84,7 @@ static SMgrRelation first_unowned_reln = NULL; /* local function prototypes */ static void smgrshutdown(int code, Datum arg); +static void add_to_unowned_list(SMgrRelation reln); static void remove_from_unowned_list(SMgrRelation reln); @@ -174,9 +175,8 @@ smgropen(RelFileNode rnode, BackendId backend) for (forknum = 0; forknum <= MAX_FORKNUM; forknum++) reln->md_fd[forknum] = NULL; - /* place it at head of unowned list (to make smgrsetowner cheap) */ - reln->next_unowned_reln = first_unowned_reln; - first_unowned_reln = reln; + /* it has no owner yet */ + add_to_unowned_list(reln); } return reln; @@ -191,7 +191,7 @@ smgropen(RelFileNode rnode, BackendId backend) void smgrsetowner(SMgrRelation *owner, SMgrRelation reln) { - /* We don't currently support "disowning" an SMgrRelation here */ + /* We don't support "disowning" an SMgrRelation here, use smgrclearowner */ Assert(owner != NULL); /* @@ -214,6 +214,40 @@ smgrsetowner(SMgrRelation *owner, SMgrRelation reln) } /* + * smgrclearowner() -- Remove long-lived reference to an SMgrRelation object + * if one exists + */ +void +smgrclearowner(SMgrRelation *owner, SMgrRelation reln) +{ + /* Do nothing if the SMgrRelation object is not owned by the owner */ + if (reln->smgr_owner != owner) + return; + + /* unset the owner's reference */ + *owner = NULL; + + /* unset our reference to the owner */ + reln->smgr_owner = NULL; + + add_to_unowned_list(reln); +} + +/* + * add_to_unowned_list -- link an SMgrRelation onto the unowned list + * + * Check remove_from_unowned_list()'s comments for performance + * considerations. + */ +static void +add_to_unowned_list(SMgrRelation reln) +{ + /* place it at head of the list (to make smgrsetowner cheap) */ + reln->next_unowned_reln = first_unowned_reln; + first_unowned_reln = reln; +} + +/* * remove_from_unowned_list -- unlink an SMgrRelation from the unowned list * * If the reln is not present in the list, nothing happens. Typically this |