11
11
*
12
12
*
13
13
* IDENTIFICATION
14
- * $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.84 2004/12/31 22:01:13 pgsql Exp $
14
+ * $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.85 2005/01/10 20:02:22 tgl Exp $
15
15
*
16
16
*-------------------------------------------------------------------------
17
17
*/
@@ -216,6 +216,7 @@ smgropen(RelFileNode rnode)
216
216
if (!found )
217
217
{
218
218
/* hash_search already filled in the lookup key */
219
+ reln -> smgr_owner = NULL ;
219
220
reln -> smgr_which = 0 ;/* we only have md.c at present */
220
221
reln -> md_fd = NULL ;/* mark it not open */
221
222
}
@@ -224,15 +225,36 @@ smgropen(RelFileNode rnode)
224
225
}
225
226
226
227
/*
227
- *smgrclose () --Close and delete an SMgrRelation object.
228
+ * smgrsetowner () --Establish a long-lived reference to an SMgrRelation object
228
229
*
229
- * It is the caller's responsibility not to leave any dangling references
230
- * to the object. (Pointers should be cleared after successful return;
231
- * on the off chance of failure, the SMgrRelation object will still exist.)
230
+ * There can be only one owner at a time; this is sufficient since currently
231
+ * the only such owners exist in the relcache.
232
+ */
233
+ void
234
+ smgrsetowner (SMgrRelation * owner ,SMgrRelation reln )
235
+ {
236
+ /*
237
+ * First, unhook any old owner. (Normally there shouldn't be any, but
238
+ * it seems possible that this can happen during swap_relation_files()
239
+ * depending on the order of processing. It's ok to close the old
240
+ * relcache entry early in that case.)
241
+ */
242
+ if (reln -> smgr_owner )
243
+ * (reln -> smgr_owner )= NULL ;
244
+
245
+ /* Now establish the ownership relationship. */
246
+ reln -> smgr_owner = owner ;
247
+ * owner = reln ;
248
+ }
249
+
250
+ /*
251
+ *smgrclose() -- Close and delete an SMgrRelation object.
232
252
*/
233
253
void
234
254
smgrclose (SMgrRelation reln )
235
255
{
256
+ SMgrRelation * owner ;
257
+
236
258
if (!(* (smgrsw [reln -> smgr_which ].smgr_close )) (reln ))
237
259
ereport (ERROR ,
238
260
(errcode_for_file_access (),
@@ -241,16 +263,24 @@ smgrclose(SMgrRelation reln)
241
263
reln -> smgr_rnode .dbNode ,
242
264
reln -> smgr_rnode .relNode )));
243
265
266
+ owner = reln -> smgr_owner ;
267
+
244
268
if (hash_search (SMgrRelationHash ,
245
269
(void * )& (reln -> smgr_rnode ),
246
270
HASH_REMOVE ,NULL )== NULL )
247
271
elog (ERROR ,"SMgrRelation hashtable corrupted" );
272
+
273
+ /*
274
+ * Unhook the owner pointer, if any. We do this last since in the
275
+ * remote possibility of failure above, the SMgrRelation object will still
276
+ * exist.
277
+ */
278
+ if (owner )
279
+ * owner = NULL ;
248
280
}
249
281
250
282
/*
251
283
*smgrcloseall() -- Close all existing SMgrRelation objects.
252
- *
253
- * It is the caller's responsibility not to leave any dangling references.
254
284
*/
255
285
void
256
286
smgrcloseall (void )
@@ -275,8 +305,6 @@ smgrcloseall(void)
275
305
* This has the same effects as smgrclose(smgropen(rnode)), but it avoids
276
306
* uselessly creating a hashtable entry only to drop it again when no
277
307
* such entry exists already.
278
- *
279
- * It is the caller's responsibility not to leave any dangling references.
280
308
*/
281
309
void
282
310
smgrclosenode (RelFileNode rnode )