[postgis-tickets] r16172 - Simplify support for PgSQL11 and other versions w/ memorycontext deleteion callbacks. References #3946.

Paul Ramsey pramsey at cleverelephant.ca
Wed Dec 20 11:28:16 PST 2017


Author: pramsey
Date: 2017-12-20 11:28:16 -0800 (Wed, 20 Dec 2017)
New Revision: 16172

Modified:
   trunk/extensions/address_standardizer/std_pg_hash.c
   trunk/libpgcommon/lwgeom_transform.c
   trunk/postgis/lwgeom_geos_prepared.c
Log:
Simplify support for PgSQL11 and other versions w/ memorycontext deleteion callbacks. References #3946.


Modified: trunk/extensions/address_standardizer/std_pg_hash.c
===================================================================
--- trunk/extensions/address_standardizer/std_pg_hash.c	2017-12-20 16:44:52 UTC (rev 16171)
+++ trunk/extensions/address_standardizer/std_pg_hash.c	2017-12-20 19:28:16 UTC (rev 16172)
@@ -91,22 +91,7 @@
 static StdHashEntry *GetStdHashEntry(MemoryContext mcxt);
 static void DeleteStdHashEntry(MemoryContext mcxt);
 
-/* Memory context cache function prototypes */
-static void StdCacheInit(MemoryContext context);
-static void StdCacheReset(MemoryContext context);
-static void StdCacheDelete(MemoryContext context);
-static bool StdCacheIsEmpty(MemoryContext context);
 
-#if POSTGIS_PGSQL_VERSION >= 96
-static void StdCacheStats(MemoryContext context, int level, bool print, MemoryContextCounters *totals);
-#else
-static void StdCacheStats(MemoryContext context, int level);
-#endif
-
-#ifdef MEMORY_CONTEXT_CHECKING
-static void StdCacheCheck(MemoryContext context);
-#endif
-
 static bool IsInStdPortalCache(StdPortalCache *STDCache,  char *lextab, char *gaztab, char *rultab);
 static STANDARDIZER *GetStdFromPortalCache(StdPortalCache *STDCache,  char *lextab, char *gaztab, char *rultab);
 static void AddToStdPortalCache(StdPortalCache *STDCache, char *lextab, char *gaztab, char *rultab);
@@ -124,41 +109,19 @@
 static int load_rules(RULES *rules, char *tabname);
 
 
-/* Memory context definition must match the current version of PostgreSQL */
-static MemoryContextMethods StdCacheContextMethods =
-{
-    NULL,
-    NULL,
-    NULL,
-    StdCacheInit,
-    StdCacheReset,
-    StdCacheDelete,
-    NULL,
-    StdCacheIsEmpty,
-    StdCacheStats
-#ifdef MEMORY_CONTEXT_CHECKING
-    , StdCacheCheck
-#endif
-};
 
 
-static void
-StdCacheInit(MemoryContext context)
-{
-    /* NOP - initialized when first used. */
-}
 
-
 static void
-StdCacheReset(MemoryContext context)
-{
-    // NOP - Seems to be a required function
-}
+#if POSTGIS_PGSQL_VERSION < 95
 
-
-static void
 StdCacheDelete(MemoryContext context)
 {
+#else
+StdCacheDelete(void *ptr)
+{
+	MemoryContext context = (MemoryContext)ptr;
+#endif
     StdHashEntry *she;
 
     DBG("Enter: StdCacheDelete");
@@ -177,7 +140,21 @@
     DeleteStdHashEntry(context);
 }
 
+#if POSTGIS_PGSQL_VERSION < 95
 
+static void
+StdCacheInit(MemoryContext context)
+{
+    /* NOP - initialized when first used. */
+}
+
+
+static void
+StdCacheReset(MemoryContext context)
+{
+    // NOP - Seems to be a required function
+}
+
 static bool
 StdCacheIsEmpty(MemoryContext context)
 {
@@ -185,24 +162,13 @@
     return FALSE;
 }
 
-
-#if POSTGIS_PGSQL_VERSION >= 96
 static void
-StdCacheStats(MemoryContext context, int level, bool print, MemoryContextCounters *totals)
-{
-    // another required function
-    fprintf(stderr, "%s: STANDARDIZER context\n", context->name);
-}
-#else
-static void
 StdCacheStats(MemoryContext context, int level)
 {
     // another required function
     fprintf(stderr, "%s: STANDARDIZER context\n", context->name);
 }
-#endif
 
-
 #ifdef MEMORY_CONTEXT_CHECKING
 static void
 StdCacheCheck(MemoryContext context)
@@ -211,7 +177,26 @@
 }
 #endif
 
+/* Memory context definition must match the current version of PostgreSQL */
+static MemoryContextMethods StdCacheContextMethods =
+{
+    NULL,
+    NULL,
+    NULL,
+    StdCacheInit,
+    StdCacheReset,
+    StdCacheDelete,
+    NULL,
+    StdCacheIsEmpty,
+    StdCacheStats
+#ifdef MEMORY_CONTEXT_CHECKING
+    , StdCacheCheck
+#endif
+};
 
+#endif /* POSTGIS_PGSQL_VERSION < 95 */
+
+
 uint32
 mcxt_ptr_hash_std(const void *key, Size keysize)
 {
@@ -397,11 +382,28 @@
 
     DBG("Adding item to STD cache ('%s', '%s', '%s') index %d", lextab, gaztab, rultab, STDCache->NextSlot);
 
+
+#if POSTGIS_PGSQL_VERSION < 95
     STDMemoryContext = MemoryContextCreate(T_AllocSetContext, 8192,
                                            &StdCacheContextMethods,
                                            STDCache->StdCacheContext,
                                            "PAGC STD Memory Context");
+#else
+	STDMemoryContext =  AllocSetContextCreate(STDCache->StdCacheContext,
+	                                          "PAGC STD Memory Context",
+	                                          ALLOCSET_SMALL_SIZES);
 
+	/* PgSQL comments suggest allocating callback in the context */
+	/* being managed, so that the callback object gets cleaned along with */
+	/* the context */
+	MemoryContextCallback *callback = MemoryContextAlloc(STDMemoryContext, sizeof(MemoryContextCallback));
+	callback->arg = (void*)(STDMemoryContext);
+	callback->func = StdCacheDelete;
+	MemoryContextRegisterResetCallback(STDMemoryContext, callback);
+#endif
+
+
+
     /* Create the backend hash if it doesn't already exist */
     DBG("Check if StdHash exists (%p)", StdHash);
     if (!StdHash)

Modified: trunk/libpgcommon/lwgeom_transform.c
===================================================================
--- trunk/libpgcommon/lwgeom_transform.c	2017-12-20 16:44:52 UTC (rev 16171)
+++ trunk/libpgcommon/lwgeom_transform.c	2017-12-20 19:28:16 UTC (rev 16172)
@@ -64,9 +64,6 @@
 {
 	MemoryContext ProjectionContext;
 	projPJ projection;
-#if POSTGIS_PGSQL_VERSION >= 96
-	MemoryContextCallback callback; /* for releasing hashentry when done */
-#endif
 }
 PJHashEntry;
 
@@ -76,10 +73,7 @@
 
 static HTAB *CreatePJHash(void);
 static void AddPJHashEntry(MemoryContext mcxt, projPJ projection);
-#if POSTGIS_PGSQL_VERSION < 96
-/** see note on function def why this is useless **/
 static projPJ GetPJHashEntry(MemoryContext mcxt);
-#endif
 static void DeletePJHashEntry(MemoryContext mcxt);
 
 /* Internal Cache API */
@@ -93,40 +87,34 @@
 static bool IsPROJ4LibPathSet = false;
 void SetPROJ4LibPath(void);
 
-#if POSTGIS_PGSQL_VERSION < 96
-static void PROJ4SRSCacheDelete(MemoryContext context);
+
+static void
+#if POSTGIS_PGSQL_VERSION < 95
+PROJ4SRSCacheDelete(MemoryContext context)
+{
 #else
-static void PROJ4SRSCacheDelete(void *arg);
+PROJ4SRSCacheDelete(void *ptr)
+{
+	MemoryContext context = (MemoryContext)ptr;
 #endif
-/* Memory context cache function prototypes
-Only need for PostgreSQL where we will not be using a built-in memory context*/
-#if POSTGIS_PGSQL_VERSION < 96
-static void PROJ4SRSCacheInit(MemoryContext context);
-static void PROJ4SRSCacheReset(MemoryContext context);
-static bool PROJ4SRSCacheIsEmpty(MemoryContext context);
+	projPJ projection;
 
-static void PROJ4SRSCacheStats(MemoryContext context, int level);
+	/* Lookup the projPJ pointer in the global hash table so we can free it */
+	projection = GetPJHashEntry(context);
 
-#ifdef MEMORY_CONTEXT_CHECKING
-static void PROJ4SRSCacheCheck(MemoryContext context);
-#endif
+	if (!projection)
+		elog(ERROR, "PROJ4SRSCacheDelete: Trying to delete non-existant projection object with MemoryContext key (%p)", (void *)context);
 
-static MemoryContextMethods PROJ4SRSCacheContextMethods =
-{
-	NULL,
-	NULL,
-	NULL,
-	PROJ4SRSCacheInit,
-	PROJ4SRSCacheReset,
-	PROJ4SRSCacheDelete,
-	NULL,
-	PROJ4SRSCacheIsEmpty,
-	PROJ4SRSCacheStats
-#ifdef MEMORY_CONTEXT_CHECKING
-	,PROJ4SRSCacheCheck
-#endif
-};
+	POSTGIS_DEBUGF(3, "deleting projection object (%p) with MemoryContext key (%p)", projection, context);
+	/* Free it */
+	pj_free(projection);
 
+	/* Remove the hash entry as it is no longer needed */
+	DeletePJHashEntry(context);
+}
+
+#if POSTGIS_PGSQL_VERSION < 95
+
 static void
 PROJ4SRSCacheInit(MemoryContext context)
 {
@@ -156,11 +144,7 @@
 }
 
 static void
-#if POSTGIS_PGSQL_VERSION >= 96
-PROJ4SRSCacheStats(MemoryContext context, int level, bool print, MemoryContextCounters *totals)
-#else
 PROJ4SRSCacheStats(MemoryContext context, int level)
-#endif
 {
 	/*
 	 * Simple stats display function - we must supply a function since this call is mandatory according to tgl
@@ -181,37 +165,25 @@
 }
 #endif
 
-#endif
-
-
-static void
-#if POSTGIS_PGSQL_VERSION < 96
-PROJ4SRSCacheDelete(MemoryContext context)
+/* Memory context definition must match the current version of PostgreSQL */
+static MemoryContextMethods PROJ4SRSCacheContextMethods =
 {
-	projPJ projection;
-	/* Lookup the projPJ pointer in the global hash table so we can free it */
-	projection = GetPJHashEntry(context);
-#else  /** to use built-in memory context we need to provide our delete hook in a form suitable for callback **/
-PROJ4SRSCacheDelete(void *arg)
-{
-	PJHashEntry *he = (PJHashEntry *) arg;
-	projPJ projection = he->projection;
-	MemoryContext context;
-	context = he->ProjectionContext;
+	NULL,
+	NULL,
+	NULL,
+	PROJ4SRSCacheInit,
+	PROJ4SRSCacheReset,
+	PROJ4SRSCacheDelete,
+	NULL,
+	PROJ4SRSCacheIsEmpty,
+	PROJ4SRSCacheStats
+#ifdef MEMORY_CONTEXT_CHECKING
+	,PROJ4SRSCacheCheck
 #endif
-	if (!projection)
-		elog(ERROR, "PROJ4SRSCacheDelete: Trying to delete non-existant projection object with MemoryContext key (%p)", (void *)context);
+};
 
-	POSTGIS_DEBUGF(3, "deleting projection object (%p) with MemoryContext key (%p)", projection, context);
+#endif /* POSTGIS_PGSQL_VERSION < 95 */
 
-	/* Free it */
-	pj_free(projection);
-
-	/* Remove the hash entry as it is no longer needed */
-	DeletePJHashEntry(context);
-}
-
-
 /*
  * PROJ4 projPJ Hash Table functions
  */
@@ -266,11 +238,6 @@
 	}
 }
 
-/** TODO: May reconsider changing this to return entry as name implies
- *  For now it's useless when we are using built-in context cause
- * we need the entry for cleanup
- * */
-#if POSTGIS_PGSQL_VERSION < 96
 static projPJ GetPJHashEntry(MemoryContext mcxt)
 {
 	void **key;
@@ -284,8 +251,8 @@
 
 	return he->projection;
 }
-#endif
 
+
 static void DeletePJHashEntry(MemoryContext mcxt)
 {
 	void **key;
@@ -566,22 +533,27 @@
 	 * store it in the backend hash
 	 */
 	POSTGIS_DEBUGF(3, "adding SRID %d with proj4text \"%s\" to query cache at index %d", srid, proj_str, PROJ4Cache->PROJ4SRSCacheCount);
-#if POSTGIS_PGSQL_VERSION < 96
+
+#if POSTGIS_PGSQL_VERSION < 95
 	PJMemoryContext = MemoryContextCreate(T_AllocSetContext, 8192,
-											&PROJ4SRSCacheContextMethods,
-											PROJ4Cache->PROJ4SRSCacheContext,
-											"PostGIS PROJ4 PJ Memory Context");
+	                                      &PROJ4SRSCacheContextMethods,
+	                                      PROJ4Cache->PROJ4SRSCacheContext,
+	                                      "PostGIS PROJ4 PJ Memory Context");
 #else
-/** TODO: Verify that CacheMemoryContext is best.  I originally tried PortalMemoryContext
- * as suggested on pg-hackers, but that caused failures in delete of hash entries,
- * I presume because PortalMemory was sometimes cleaned before delete happened.  **/
-	PJMemoryContext = AllocSetContextCreate(CacheMemoryContext,
-											 "PostGIS PROJ4 PJ Memory Context",
-											 ALLOCSET_SMALL_SIZES);
+	PJMemoryContext = AllocSetContextCreate(PROJ4Cache->PROJ4SRSCacheContext,
+	                                        "PostGIS PROJ4 PJ Memory Context",
+	                                        ALLOCSET_SMALL_SIZES);
 
+	/* PgSQL comments suggest allocating callback in the context */
+	/* being managed, so that the callback object gets cleaned along with */
+	/* the context */
+	MemoryContextCallback *callback = MemoryContextAlloc(PJMemoryContext, sizeof(MemoryContextCallback));
+	callback->arg = (void*)PJMemoryContext;
+	callback->func = PROJ4SRSCacheDelete;
+	MemoryContextRegisterResetCallback(PJMemoryContext, callback);
 #endif
 
-	/* Create the backend hash if it doesn't already exist */
+ 	/* Create the backend hash if it doesn't already exist */
 	if (!PJHash)
 		PJHash = CreatePJHash();
 
@@ -593,25 +565,6 @@
 
 	AddPJHashEntry(PJMemoryContext, projection);
 
-	/* Register cleanup callback only for PostgreSQL where
-	 * we are using built-in context instead of our own
-	 */
-	#if POSTGIS_PGSQL_VERSION >= 96
-	/* The hash key is the MemoryContext pointer */
-	void **key;
-	key = (void *)&PJMemoryContext;
-	/** We need to do this because GetPJHashEntry returns the projection
-	 * and NOT the entry as the name would lead you to believe **/
-	PJHashEntry *he;
-
-	/* Return the projection object from the hash */
-	he = (PJHashEntry *) hash_search(PJHash, key, HASH_FIND, NULL);
-	he->callback.func = PROJ4SRSCacheDelete;
-	he->callback.arg = (void *) he;
-	MemoryContextRegisterResetCallback(he->ProjectionContext,
-										&he->callback);
-	#endif
-
 	PROJ4Cache->PROJ4SRSCache[PROJ4Cache->PROJ4SRSCacheCount].srid = srid;
 	PROJ4Cache->PROJ4SRSCache[PROJ4Cache->PROJ4SRSCacheCount].projection = projection;
 	PROJ4Cache->PROJ4SRSCache[PROJ4Cache->PROJ4SRSCacheCount].projection_mcxt = PJMemoryContext;
@@ -700,52 +653,7 @@
 	return (Proj4Cache)GetPROJ4SRSCache(fcinfo);
 }
 
-#if 0
-static PROJ4PortalCache *GetPROJ4SRSCache(FunctionCallInfo fcinfo)
-{
-	PROJ4PortalCache *PROJ4Cache = (GetGeomCache(fcinfo))->proj;
 
-	/*
-	 * If we have not already created PROJ4 cache for this portal
-	 * then create it
-	 */
-	if (fcinfo->flinfo->fn_extra == NULL)
-	{
-		MemoryContext old_context;
-
-		old_context = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
-		PROJ4Cache = palloc(sizeof(PROJ4PortalCache));
-		MemoryContextSwitchTo(old_context);
-
-		if (PROJ4Cache)
-		{
-			int i;
-
-			POSTGIS_DEBUGF(3, "Allocating PROJ4Cache for portal with transform() MemoryContext %p", fcinfo->flinfo->fn_mcxt);
-			/* Put in any required defaults */
-			for (i = 0; i < PROJ4_CACHE_ITEMS; i++)
-			{
-				PROJ4Cache->PROJ4SRSCache[i].srid = SRID_UNKNOWN;
-				PROJ4Cache->PROJ4SRSCache[i].projection = NULL;
-				PROJ4Cache->PROJ4SRSCache[i].projection_mcxt = NULL;
-			}
-			PROJ4Cache->PROJ4SRSCacheCount = 0;
-			PROJ4Cache->PROJ4SRSCacheContext = fcinfo->flinfo->fn_mcxt;
-
-			/* Store the pointer in fcinfo->flinfo->fn_extra */
-			fcinfo->flinfo->fn_extra = PROJ4Cache;
-		}
-	}
-	else
-	{
-		/* Use the existing cache */
-		PROJ4Cache = fcinfo->flinfo->fn_extra;
-	}
-
-	return PROJ4Cache ;
-}
-#endif
-
 int
 GetProjectionsUsingFCInfo(FunctionCallInfo fcinfo, int srid1, int srid2, projPJ *pj1, projPJ *pj2)
 {

Modified: trunk/postgis/lwgeom_geos_prepared.c
===================================================================
--- trunk/postgis/lwgeom_geos_prepared.c	2017-12-20 16:44:52 UTC (rev 16171)
+++ trunk/postgis/lwgeom_geos_prepared.c	2017-12-20 19:28:16 UTC (rev 16172)
@@ -79,14 +79,11 @@
 
 #define PREPARED_BACKEND_HASH_SIZE	32
 
-typedef struct PrepGeomHashEntry
+typedef struct
 {
 	MemoryContext context;
 	const GEOSPreparedGeometry* prepared_geom;
 	const GEOSGeometry* geom;
-#if POSTGIS_PGSQL_VERSION >= 96
-	MemoryContextCallback callback; /* for releasing hashentry when done */
-#endif
 }
 PrepGeomHashEntry;
 
@@ -97,41 +94,38 @@
 static PrepGeomHashEntry *GetPrepGeomHashEntry(MemoryContext mcxt);
 static void DeletePrepGeomHashEntry(MemoryContext mcxt);
 
-#if POSTGIS_PGSQL_VERSION < 96
-static void PreparedCacheDelete(MemoryContext context);
+
+static void
+#if POSTGIS_PGSQL_VERSION < 95
+PreparedCacheDelete(MemoryContext context)
+{
 #else
-static void  PreparedCacheDelete(void *arg);
+PreparedCacheDelete(void *ptr)
+{
+	MemoryContext context = (MemoryContext)ptr;
 #endif
-/* Memory context cache function prototypes
-Only need for PostgreSQL where we will not be using a built-in memory context*/
-#if POSTGIS_PGSQL_VERSION < 96
-static void PreparedCacheInit(MemoryContext context);
-static void PreparedCacheReset(MemoryContext context);
 
-static bool PreparedCacheIsEmpty(MemoryContext context);
+	PrepGeomHashEntry* pghe;
 
-static void PreparedCacheStats(MemoryContext context, int level);
+	/* Lookup the hash entry pointer in the global hash table so we can free it */
+	pghe = GetPrepGeomHashEntry(context);
 
-#ifdef MEMORY_CONTEXT_CHECKING
-static void PreparedCacheCheck(MemoryContext context);
-#endif
+	if (!pghe)
+		elog(ERROR, "PreparedCacheDelete: Trying to delete non-existant hash entry object with MemoryContext key (%p)", (void *)context);
 
-static MemoryContextMethods PreparedCacheContextMethods =
-{
-	NULL,
-	NULL,
-	NULL,
-	PreparedCacheInit,
-	PreparedCacheReset,
-	PreparedCacheDelete,
-	NULL,
-	PreparedCacheIsEmpty,
-	PreparedCacheStats
-#ifdef MEMORY_CONTEXT_CHECKING
-	, PreparedCacheCheck
-#endif
-};
+	POSTGIS_DEBUGF(3, "deleting geom object (%p) and prepared geom object (%p) with MemoryContext key (%p)", pghe->geom, pghe->prepared_geom, context);
 
+	/* Free them */
+	if ( pghe->prepared_geom )
+		GEOSPreparedGeom_destroy( pghe->prepared_geom );
+	if ( pghe->geom )
+		GEOSGeom_destroy( (GEOSGeometry *)pghe->geom );
+
+	/* Remove the hash entry as it is no longer needed */
+	DeletePrepGeomHashEntry(context);
+}
+
+#if POSTGIS_PGSQL_VERSION < 95
 static void
 PreparedCacheInit(MemoryContext context)
 {
@@ -141,7 +135,6 @@
 	 */
 }
 
-
 static void
 PreparedCacheReset(MemoryContext context)
 {
@@ -169,7 +162,6 @@
 	 * (see postgis-devel archives July 2007)
 	   fprintf(stderr, "%s: Prepared context\n", context->name);
 	 */
-
 }
 
 #ifdef MEMORY_CONTEXT_CHECKING
@@ -182,41 +174,28 @@
 	 */
 }
 #endif
-#endif
 
-
-
-static void
-#if POSTGIS_PGSQL_VERSION < 96
-PreparedCacheDelete(MemoryContext context)
+/* Memory context definition must match the current version of PostgreSQL */
+static MemoryContextMethods PreparedCacheContextMethods =
 {
-	PrepGeomHashEntry* pghe;
-	/* Lookup the hash entry pointer in the global hash table so we can free it */
-	pghe = GetPrepGeomHashEntry(context);
-#else  /** to use built-in memory context we need to provide our delete hook in a form suitable for callback **/
-PreparedCacheDelete(void *arg)
-{
-	PrepGeomHashEntry *pghe =  (PrepGeomHashEntry *) arg;
-	MemoryContext context;
-	if (pghe)
-		context = pghe->context;
+	NULL,
+	NULL,
+	NULL,
+	PreparedCacheInit,
+	PreparedCacheReset,
+	PreparedCacheDelete,
+	NULL,
+	PreparedCacheIsEmpty,
+	PreparedCacheStats
+#ifdef MEMORY_CONTEXT_CHECKING
+	, PreparedCacheCheck
 #endif
-	if (!pghe)
-		elog(ERROR, "PreparedCacheDelete: Trying to delete non-existant hash entry object with MemoryContext key (%p)", (void *)context);
+};
 
-	POSTGIS_DEBUGF(3, "deleting geom object (%p) and prepared geom object (%p) with MemoryContext key (%p)", pghe->geom, pghe->prepared_geom, context);
+#endif /* POSTGIS_PGSQL_VERSION < 95 */
 
-	/* Free them */
-	if ( pghe->prepared_geom )
-		GEOSPreparedGeom_destroy( pghe->prepared_geom );
-	if ( pghe->geom )
-		GEOSGeom_destroy( (GEOSGeometry *)pghe->geom );
 
-	/* Remove the hash entry as it is no longer needed */
-	DeletePrepGeomHashEntry(context);
-}
 
-
 /* TODO: put this in common are for both transform and prepared
 ** mcxt_ptr_hash
 ** Build a key from a pointer and a size value.
@@ -321,6 +300,7 @@
 {
 	PrepGeomCache* prepcache = (PrepGeomCache*)cache;
 	PrepGeomHashEntry* pghe;
+
 	/*
 	* First time through? allocate the global hash.
 	*/
@@ -332,26 +312,27 @@
 	*/
 	if ( ! prepcache->context_callback )
 	{
-		/** TODO: This is yucky that we are reusing the same variable name
-		 * we used as a global pointer above, as a local variable.  We should reconsider this.
-		 * Took me a while to realize they weren't the same. **/
 		PrepGeomHashEntry pghe;
-		#if POSTGIS_PGSQL_VERSION < 96
-			prepcache->context_callback = MemoryContextCreate(T_AllocSetContext, 8192,
-											&PreparedCacheContextMethods,
-											prepcache->context_statement,
-											"PostGIS Prepared Geometry Context");
-		#else
-/**For 9.5+ we can use a PostgreSQL context instead of creating our own and add a delete callback to it.
- * TODO: change so not just PostgreSQL 11 goes thru this loop **/
-/** TODO: Verify that CacheMemoryContext is best.  I originally tried PortalMemoryContext
- * as suggested on pg-hackers, but that caused failures in delete of hash entries,
- * I presume because PortalMemory was sometimes cleaned before delete happened.  **/
-			prepcache->context_callback = AllocSetContextCreate(CacheMemoryContext,
-											 "PostGIS PROJ4 PJ Memory Context",
-											ALLOCSET_SMALL_SIZES
-			);
-		#endif
+#if POSTGIS_PGSQL_VERSION < 95
+		prepcache->context_callback = MemoryContextCreate(T_AllocSetContext, 8192,
+		                             &PreparedCacheContextMethods,
+		                             prepcache->context_statement,
+		                             "PostGIS Prepared Geometry Context");
+
+#else
+		prepcache->context_callback = AllocSetContextCreate(prepcache->context_statement,
+	                                   "PostGIS Prepared Geometry Context",
+	                                   ALLOCSET_SMALL_SIZES);
+
+		/* PgSQL comments suggest allocating callback in the context */
+		/* being managed, so that the callback object gets cleaned along with */
+		/* the context */
+		MemoryContextCallback *callback = MemoryContextAlloc(prepcache->context_callback, sizeof(MemoryContextCallback));
+		callback->arg = (void*)(prepcache->context_callback);
+		callback->func = PreparedCacheDelete;
+		MemoryContextRegisterResetCallback(prepcache->context_callback, callback);
+#endif
+
 		pghe.context = prepcache->context_callback;
 		pghe.geom = 0;
 		pghe.prepared_geom = 0;
@@ -389,15 +370,6 @@
 	* extra references in a global hash object.
 	*/
 	pghe = GetPrepGeomHashEntry(prepcache->context_callback);
-
-	#if POSTGIS_PGSQL_VERSION >= 96
-	/* Immediately register cleanup callback only for PostgreSQL where
-	 we are using built in context instead of our own  */
-	pghe->callback.func = PreparedCacheDelete;
-	pghe->callback.arg = (void *) pghe;
-	MemoryContextRegisterResetCallback(pghe->context,
-										&pghe->callback);
-	#endif
 	if ( ! pghe )
 	{
 		lwpgerror("PrepGeomCacheBuilder failed to find hash entry for context %p", prepcache->context_callback);
@@ -407,8 +379,6 @@
 	pghe->geom = prepcache->geom;
 	pghe->prepared_geom = prepcache->prepared_geom;
 
-
-
 	return LW_SUCCESS;
 }
 



More information about the postgis-tickets mailing list