aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/utils/mmgr/dsa.c38
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] =