diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/utils/mmgr/dsa.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/src/backend/utils/mmgr/dsa.c b/src/backend/utils/mmgr/dsa.c index 8d1aace40ac..c392a9eabc1 100644 --- a/src/backend/utils/mmgr/dsa.c +++ b/src/backend/utils/mmgr/dsa.c @@ -59,6 +59,7 @@ #include "utils/dsa.h" #include "utils/freepage.h" #include "utils/memutils.h" +#include "utils/resowner.h" /* * The size of the initial DSM segment that backs a dsa_area created by @@ -368,8 +369,13 @@ struct dsa_area /* Pointer to the control object in shared memory. */ dsa_area_control *control; - /* Has the mapping been pinned? */ - bool mapping_pinned; + /* + * All the mappings are owned by this. The dsa_area itself is not + * directly tracked by the ResourceOwner, but the effect is the same. NULL + * if the attachment has session lifespan, i.e if dsa_pin_mapping() has + * been called. + */ + ResourceOwner resowner; /* * This backend's array of segment maps, ordered by segment index @@ -645,12 +651,14 @@ dsa_pin_mapping(dsa_area *area) { int i; - Assert(!area->mapping_pinned); - area->mapping_pinned = true; + if (area->resowner != NULL) + { + area->resowner = NULL; - for (i = 0; i <= area->high_segment_index; ++i) - if (area->segment_maps[i].segment != NULL) - dsm_pin_mapping(area->segment_maps[i].segment); + for (i = 0; i <= area->high_segment_index; ++i) + if (area->segment_maps[i].segment != NULL) + dsm_pin_mapping(area->segment_maps[i].segment); + } } /* @@ -1264,7 +1272,7 @@ create_internal(void *place, size_t size, */ area = palloc(sizeof(dsa_area)); area->control = control; - area->mapping_pinned = false; + area->resowner = CurrentResourceOwner; memset(area->segment_maps, 0, sizeof(dsa_segment_map) * DSA_MAX_SEGMENTS); area->high_segment_index = 0; area->freed_segment_counter = 0; @@ -1320,7 +1328,7 @@ attach_internal(void *place, dsm_segment *segment, dsa_handle handle) /* Build the backend-local area object. */ area = palloc(sizeof(dsa_area)); area->control = control; - area->mapping_pinned = false; + area->resowner = CurrentResourceOwner; memset(&area->segment_maps[0], 0, sizeof(dsa_segment_map) * DSA_MAX_SEGMENTS); area->high_segment_index = 0; @@ -1743,6 +1751,7 @@ get_segment_by_index(dsa_area *area, dsa_segment_index index) dsm_handle handle; dsm_segment *segment; dsa_segment_map *segment_map; + ResourceOwner oldowner; /* * If we are reached by dsa_free or dsa_get_address, there must be at @@ -1761,11 +1770,12 @@ get_segment_by_index(dsa_area *area, dsa_segment_index index) elog(ERROR, "dsa_area could not attach to a segment that has been freed"); + oldowner = CurrentResourceOwner; + CurrentResourceOwner = area->resowner; segment = dsm_attach(handle); + CurrentResourceOwner = oldowner; if (segment == NULL) elog(ERROR, "dsa_area could not attach to segment"); - if (area->mapping_pinned) - dsm_pin_mapping(segment); segment_map = &area->segment_maps[index]; segment_map->segment = segment; segment_map->mapped_address = dsm_segment_address(segment); @@ -2067,6 +2077,7 @@ make_new_segment(dsa_area *area, size_t requested_pages) size_t usable_pages; dsa_segment_map *segment_map; dsm_segment *segment; + ResourceOwner oldowner; Assert(LWLockHeldByMe(DSA_AREA_LOCK(area))); @@ -2151,12 +2162,13 @@ make_new_segment(dsa_area *area, size_t requested_pages) } /* Create the segment. */ + oldowner = CurrentResourceOwner; + CurrentResourceOwner = area->resowner; segment = dsm_create(total_size, 0); + CurrentResourceOwner = oldowner; if (segment == NULL) return NULL; dsm_pin_segment(segment); - if (area->mapping_pinned) - dsm_pin_mapping(segment); /* Store the handle in shared memory to be found by index. */ area->control->segment_handles[new_index] = |