1996-07-09 08:22:35 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* portalmem.c--
|
1997-09-07 07:04:48 +02:00
|
|
|
* backend portal memory context management stuff
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
1998-09-01 06:40:42 +02:00
|
|
|
* $Header: /cvsroot/pgsql/src/backend/utils/mmgr/portalmem.c,v 1.14 1998/09/01 04:33:39 momjian Exp $
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
* NOTES
|
1997-09-07 07:04:48 +02:00
|
|
|
* Do not confuse "Portal" with "PortalEntry" (or "PortalBuffer").
|
|
|
|
* When a PQexec() routine is run, the resulting tuples
|
|
|
|
* find their way into a "PortalEntry". The contents of the resulting
|
|
|
|
* "PortalEntry" can then be inspected by other PQxxx functions.
|
|
|
|
*
|
|
|
|
* A "Portal" is a structure used to keep track of queries of the
|
|
|
|
* form:
|
|
|
|
* retrieve portal FOO ( blah... ) where blah...
|
|
|
|
*
|
|
|
|
* When the backend sees a "retrieve portal" query, it allocates
|
|
|
|
* a "PortalD" structure, plans the query and then stores the query
|
|
|
|
* in the portal without executing it. Later, when the backend
|
|
|
|
* sees a
|
|
|
|
* fetch 1 into FOO
|
|
|
|
*
|
|
|
|
* the system looks up the portal named "FOO" in the portal table,
|
|
|
|
* gets the planned query and then calls the executor with a feature of
|
|
|
|
* '(EXEC_FOR 1). The executor then runs the query and returns a single
|
|
|
|
* tuple. The problem is that we have to hold onto the state of the
|
|
|
|
* portal query until we see a "close p". This means we have to be
|
|
|
|
* careful about memory management.
|
|
|
|
*
|
|
|
|
* Having said all that, here is what a PortalD currently looks like:
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* struct PortalD {
|
1997-09-07 07:04:48 +02:00
|
|
|
* char* name;
|
|
|
|
* classObj(PortalVariableMemory) variable;
|
|
|
|
* classObj(PortalHeapMemory) heap;
|
|
|
|
* List queryDesc;
|
|
|
|
* EState state;
|
|
|
|
* void (*cleanup) ARGS((Portal portal));
|
1996-07-09 08:22:35 +02:00
|
|
|
* };
|
|
|
|
*
|
1997-09-07 07:04:48 +02:00
|
|
|
* I hope this makes things clearer to whoever reads this -cim 2/22/91
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
1997-09-07 07:04:48 +02:00
|
|
|
* Here is an old comment taken from nodes/memnodes.h
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* MemoryContext --
|
1997-09-07 07:04:48 +02:00
|
|
|
* A logical context in which memory allocations occur.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* The types of memory contexts can be thought of as members of the
|
|
|
|
* following inheritance hierarchy with properties summarized below.
|
|
|
|
*
|
1997-09-07 07:04:48 +02:00
|
|
|
* Node
|
|
|
|
* |
|
|
|
|
* MemoryContext___
|
|
|
|
* / \
|
|
|
|
* GlobalMemory PortalMemoryContext
|
|
|
|
* / \
|
|
|
|
* PortalVariableMemory PortalHeapMemory
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
1997-09-07 07:04:48 +02:00
|
|
|
* Flushed at Flushed at Checkpoints
|
|
|
|
* Transaction Portal
|
|
|
|
* Commit Close
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
1997-09-07 07:04:48 +02:00
|
|
|
* GlobalMemory n n n
|
|
|
|
* PortalVariableMemory n y n
|
|
|
|
* PortalHeapMemory y y y *
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*/
|
1997-09-07 07:04:48 +02:00
|
|
|
#include <stdio.h> /* for sprintf() */
|
|
|
|
#include <string.h> /* for strlen, strncpy */
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1996-11-03 07:54:38 +01:00
|
|
|
#include "postgres.h"
|
1996-07-09 08:22:35 +02:00
|
|
|
|
|
|
|
#include "lib/hasht.h"
|
|
|
|
#include "utils/module.h"
|
1997-09-07 07:04:48 +02:00
|
|
|
#include "utils/excid.h" /* for Unimplemented */
|
1996-07-09 08:22:35 +02:00
|
|
|
#include "utils/mcxt.h"
|
|
|
|
#include "utils/hsearch.h"
|
|
|
|
|
|
|
|
#include "nodes/memnodes.h"
|
|
|
|
#include "nodes/nodes.h"
|
|
|
|
#include "nodes/pg_list.h"
|
|
|
|
#include "nodes/execnodes.h" /* for EState */
|
|
|
|
|
|
|
|
#include "utils/portal.h"
|
|
|
|
|
1997-09-08 23:56:23 +02:00
|
|
|
static void CollectNamedPortals(Portal *portalP, int destroy);
|
1997-09-08 04:41:22 +02:00
|
|
|
static Portal PortalHeapMemoryGetPortal(PortalHeapMemory context);
|
1997-08-19 23:40:56 +02:00
|
|
|
static PortalVariableMemory PortalHeapMemoryGetVariableMemory(PortalHeapMemory context);
|
1997-09-08 04:41:22 +02:00
|
|
|
static void PortalResetHeapMemory(Portal portal);
|
|
|
|
static Portal PortalVariableMemoryGetPortal(PortalVariableMemory context);
|
1997-08-19 23:40:56 +02:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
/* ----------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* ALLOCFREE_ERROR_ABORT
|
|
|
|
* define this if you want a core dump when you try to
|
|
|
|
* free memory already freed -cim 2/9/91
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------
|
|
|
|
*/
|
|
|
|
#undef ALLOCFREE_ERROR_ABORT
|
|
|
|
|
|
|
|
/* ----------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* Global state
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------
|
|
|
|
*/
|
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
static int PortalManagerEnableCount = 0;
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
#define MAX_PORTALNAME_LEN 64 /* XXX LONGALIGNable value */
|
|
|
|
|
|
|
|
typedef struct portalhashent
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
char portalname[MAX_PORTALNAME_LEN];
|
|
|
|
Portal portal;
|
1997-09-08 23:56:23 +02:00
|
|
|
} PortalHashEnt;
|
1996-07-09 08:22:35 +02:00
|
|
|
|
|
|
|
#define PortalManagerEnabled (PortalManagerEnableCount >= 1)
|
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
static HTAB *PortalHashTable = NULL;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
#define PortalHashTableLookup(NAME, PORTAL) \
|
1998-06-15 20:40:05 +02:00
|
|
|
do { \
|
|
|
|
PortalHashEnt *hentry; bool found; char key[MAX_PORTALNAME_LEN]; \
|
|
|
|
\
|
|
|
|
MemSet(key, 0, MAX_PORTALNAME_LEN); \
|
|
|
|
sprintf(key, "%s", NAME); \
|
|
|
|
hentry = (PortalHashEnt*)hash_search(PortalHashTable, \
|
|
|
|
key, HASH_FIND, &found); \
|
|
|
|
if (hentry == NULL) \
|
|
|
|
elog(FATAL, "error in PortalHashTable"); \
|
|
|
|
if (found) \
|
|
|
|
PORTAL = hentry->portal; \
|
|
|
|
else \
|
|
|
|
PORTAL = NULL; \
|
|
|
|
} while(0)
|
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
#define PortalHashTableInsert(PORTAL) \
|
1998-06-15 20:40:05 +02:00
|
|
|
do { \
|
|
|
|
PortalHashEnt *hentry; bool found; char key[MAX_PORTALNAME_LEN]; \
|
|
|
|
\
|
|
|
|
MemSet(key, 0, MAX_PORTALNAME_LEN); \
|
|
|
|
sprintf(key, "%s", PORTAL->name); \
|
|
|
|
hentry = (PortalHashEnt*)hash_search(PortalHashTable, \
|
|
|
|
key, HASH_ENTER, &found); \
|
|
|
|
if (hentry == NULL) \
|
|
|
|
elog(FATAL, "error in PortalHashTable"); \
|
|
|
|
if (found) \
|
|
|
|
elog(NOTICE, "trying to insert a portal name that exists."); \
|
|
|
|
hentry->portal = PORTAL; \
|
|
|
|
} while(0)
|
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
#define PortalHashTableDelete(PORTAL) \
|
1998-06-15 20:40:05 +02:00
|
|
|
{ \
|
|
|
|
PortalHashEnt *hentry; bool found; char key[MAX_PORTALNAME_LEN]; \
|
|
|
|
\
|
|
|
|
MemSet(key, 0, MAX_PORTALNAME_LEN); \
|
|
|
|
sprintf(key, "%s", PORTAL->name); \
|
|
|
|
hentry = (PortalHashEnt*)hash_search(PortalHashTable, \
|
|
|
|
key, HASH_REMOVE, &found); \
|
|
|
|
if (hentry == NULL) \
|
|
|
|
elog(FATAL, "error in PortalHashTable"); \
|
|
|
|
if (!found) \
|
|
|
|
elog(NOTICE, "trying to delete portal name that does not exist."); \
|
|
|
|
} while(0)
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
static GlobalMemory PortalMemory = NULL;
|
1997-09-08 04:41:22 +02:00
|
|
|
static char PortalMemoryName[] = "Portal";
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
static Portal BlankPortal = NULL;
|
1996-07-09 08:22:35 +02:00
|
|
|
|
|
|
|
/* ----------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* Internal class definitions
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------
|
|
|
|
*/
|
1997-09-07 07:04:48 +02:00
|
|
|
typedef struct HeapMemoryBlockData
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
AllocSetData setData;
|
|
|
|
FixedItemData itemData;
|
1997-09-08 23:56:23 +02:00
|
|
|
} HeapMemoryBlockData;
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
typedef HeapMemoryBlockData *HeapMemoryBlock;
|
1996-07-09 08:22:35 +02:00
|
|
|
|
|
|
|
#define HEAPMEMBLOCK(context) \
|
1997-09-07 07:04:48 +02:00
|
|
|
((HeapMemoryBlock)(context)->block)
|
1996-07-09 08:22:35 +02:00
|
|
|
|
|
|
|
/* ----------------------------------------------------------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* Variable and heap memory methods
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
/* ----------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* PortalVariableMemoryAlloc
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------
|
|
|
|
*/
|
1997-09-08 04:41:22 +02:00
|
|
|
static Pointer
|
1996-07-09 08:22:35 +02:00
|
|
|
PortalVariableMemoryAlloc(PortalVariableMemory this,
|
1997-09-07 07:04:48 +02:00
|
|
|
Size size)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1998-09-01 05:29:17 +02:00
|
|
|
return AllocSetAlloc(&this->setData, size);
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* PortalVariableMemoryFree
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
PortalVariableMemoryFree(PortalVariableMemory this,
|
1997-09-07 07:04:48 +02:00
|
|
|
Pointer pointer)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
AllocSetFree(&this->setData, pointer);
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* PortalVariableMemoryRealloc
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------
|
|
|
|
*/
|
1997-09-08 04:41:22 +02:00
|
|
|
static Pointer
|
1996-07-09 08:22:35 +02:00
|
|
|
PortalVariableMemoryRealloc(PortalVariableMemory this,
|
1997-09-07 07:04:48 +02:00
|
|
|
Pointer pointer,
|
|
|
|
Size size)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1998-09-01 05:29:17 +02:00
|
|
|
return AllocSetRealloc(&this->setData, pointer, size);
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* PortalVariableMemoryGetName
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------
|
|
|
|
*/
|
1997-09-08 04:41:22 +02:00
|
|
|
static char *
|
1996-07-09 08:22:35 +02:00
|
|
|
PortalVariableMemoryGetName(PortalVariableMemory this)
|
|
|
|
{
|
1998-09-01 05:29:17 +02:00
|
|
|
return form("%s-var", PortalVariableMemoryGetPortal(this)->name);
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* PortalVariableMemoryDump
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
PortalVariableMemoryDump(PortalVariableMemory this)
|
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
printf("--\n%s:\n", PortalVariableMemoryGetName(this));
|
|
|
|
|
|
|
|
AllocSetDump(&this->setData); /* XXX is this the right interface */
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* PortalHeapMemoryAlloc
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------
|
|
|
|
*/
|
1997-09-08 04:41:22 +02:00
|
|
|
static Pointer
|
1996-07-09 08:22:35 +02:00
|
|
|
PortalHeapMemoryAlloc(PortalHeapMemory this,
|
1997-09-07 07:04:48 +02:00
|
|
|
Size size)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
HeapMemoryBlock block = HEAPMEMBLOCK(this);
|
|
|
|
|
|
|
|
AssertState(PointerIsValid(block));
|
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return AllocSetAlloc(&block->setData, size);
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* PortalHeapMemoryFree
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
PortalHeapMemoryFree(PortalHeapMemory this,
|
1997-09-07 07:04:48 +02:00
|
|
|
Pointer pointer)
|
|
|
|
{
|
|
|
|
HeapMemoryBlock block = HEAPMEMBLOCK(this);
|
|
|
|
|
|
|
|
AssertState(PointerIsValid(block));
|
|
|
|
|
|
|
|
if (AllocSetContains(&block->setData, pointer))
|
|
|
|
AllocSetFree(&block->setData, pointer);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
elog(NOTICE,
|
|
|
|
"PortalHeapMemoryFree: 0x%x not in alloc set!",
|
|
|
|
pointer);
|
1996-07-09 08:22:35 +02:00
|
|
|
#ifdef ALLOCFREE_ERROR_ABORT
|
1997-09-07 07:04:48 +02:00
|
|
|
Assert(AllocSetContains(&block->setData, pointer));
|
1998-09-01 06:40:42 +02:00
|
|
|
#endif /* ALLOCFREE_ERROR_ABORT */
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* PortalHeapMemoryRealloc
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------
|
|
|
|
*/
|
1997-09-08 04:41:22 +02:00
|
|
|
static Pointer
|
1996-07-09 08:22:35 +02:00
|
|
|
PortalHeapMemoryRealloc(PortalHeapMemory this,
|
1997-09-07 07:04:48 +02:00
|
|
|
Pointer pointer,
|
|
|
|
Size size)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
HeapMemoryBlock block = HEAPMEMBLOCK(this);
|
|
|
|
|
|
|
|
AssertState(PointerIsValid(block));
|
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return AllocSetRealloc(&block->setData, pointer, size);
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* PortalHeapMemoryGetName
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------
|
|
|
|
*/
|
1997-09-08 04:41:22 +02:00
|
|
|
static char *
|
1996-07-09 08:22:35 +02:00
|
|
|
PortalHeapMemoryGetName(PortalHeapMemory this)
|
|
|
|
{
|
1998-09-01 05:29:17 +02:00
|
|
|
return form("%s-heap", PortalHeapMemoryGetPortal(this)->name);
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* PortalHeapMemoryDump
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
PortalHeapMemoryDump(PortalHeapMemory this)
|
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
HeapMemoryBlock block;
|
|
|
|
|
|
|
|
printf("--\n%s:\n", PortalHeapMemoryGetName(this));
|
|
|
|
|
|
|
|
/* XXX is this the right interface */
|
|
|
|
if (PointerIsValid(this->block))
|
|
|
|
AllocSetDump(&HEAPMEMBLOCK(this)->setData);
|
|
|
|
|
|
|
|
/* dump the stack too */
|
|
|
|
for (block = (HeapMemoryBlock) FixedStackGetTop(&this->stackData);
|
|
|
|
PointerIsValid(block);
|
|
|
|
block = (HeapMemoryBlock)
|
|
|
|
FixedStackGetNext(&this->stackData, (Pointer) block))
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("--\n");
|
|
|
|
AllocSetDump(&block->setData);
|
|
|
|
}
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* variable / heap context method tables
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------------------------------------------------------
|
|
|
|
*/
|
1997-09-07 07:04:48 +02:00
|
|
|
static struct MemoryContextMethodsData PortalVariableContextMethodsData = {
|
|
|
|
PortalVariableMemoryAlloc, /* Pointer (*)(this, uint32) palloc */
|
|
|
|
PortalVariableMemoryFree, /* void (*)(this, Pointer) pfree */
|
|
|
|
PortalVariableMemoryRealloc,/* Pointer (*)(this, Pointer) repalloc */
|
|
|
|
PortalVariableMemoryGetName,/* char* (*)(this) getName */
|
|
|
|
PortalVariableMemoryDump /* void (*)(this) dump */
|
1996-07-09 08:22:35 +02:00
|
|
|
};
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
static struct MemoryContextMethodsData PortalHeapContextMethodsData = {
|
|
|
|
PortalHeapMemoryAlloc, /* Pointer (*)(this, uint32) palloc */
|
|
|
|
PortalHeapMemoryFree, /* void (*)(this, Pointer) pfree */
|
|
|
|
PortalHeapMemoryRealloc, /* Pointer (*)(this, Pointer) repalloc */
|
|
|
|
PortalHeapMemoryGetName, /* char* (*)(this) getName */
|
|
|
|
PortalHeapMemoryDump /* void (*)(this) dump */
|
1996-07-09 08:22:35 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* private internal support routines
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
/* ----------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* CreateNewBlankPortal
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
CreateNewBlankPortal()
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
Portal portal;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
AssertState(!PortalIsValid(BlankPortal));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* make new portal structure
|
|
|
|
*/
|
|
|
|
portal = (Portal)
|
|
|
|
MemoryContextAlloc((MemoryContext) PortalMemory, sizeof *portal);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* initialize portal variable context
|
|
|
|
*/
|
1997-09-08 23:56:23 +02:00
|
|
|
NodeSetTag((Node *) &portal->variable, T_PortalVariableMemory);
|
1997-09-07 07:04:48 +02:00
|
|
|
AllocSetInit(&portal->variable.setData, DynamicAllocMode, (Size) 0);
|
|
|
|
portal->variable.method = &PortalVariableContextMethodsData;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* initialize portal heap context
|
|
|
|
*/
|
1997-09-08 23:56:23 +02:00
|
|
|
NodeSetTag((Node *) &portal->heap, T_PortalHeapMemory);
|
1997-09-07 07:04:48 +02:00
|
|
|
portal->heap.block = NULL;
|
|
|
|
FixedStackInit(&portal->heap.stackData,
|
|
|
|
offsetof(HeapMemoryBlockData, itemData));
|
|
|
|
portal->heap.method = &PortalHeapContextMethodsData;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* set bogus portal name
|
|
|
|
*/
|
|
|
|
portal->name = "** Blank Portal **";
|
|
|
|
|
|
|
|
/* initialize portal query */
|
|
|
|
portal->queryDesc = NULL;
|
|
|
|
portal->attinfo = NULL;
|
|
|
|
portal->state = NULL;
|
|
|
|
portal->cleanup = NULL;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* install blank portal
|
|
|
|
*/
|
|
|
|
BlankPortal = portal;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
PortalNameIsSpecial(char *pname)
|
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
if (strcmp(pname, VACPNAME) == 0)
|
|
|
|
return true;
|
|
|
|
return false;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This routine is used to collect all portals created in this xaction
|
|
|
|
* and then destroy them. There is a little trickiness required as a
|
|
|
|
* result of the dynamic hashing interface to getting every hash entry
|
|
|
|
* sequentially. Its use of static variables requires that we get every
|
|
|
|
* entry *before* we destroy anything (destroying updates the hashtable
|
|
|
|
* and screws up the sequential walk of the table). -mer 17 Aug 1992
|
|
|
|
*/
|
1997-08-19 23:40:56 +02:00
|
|
|
static void
|
1997-09-08 23:56:23 +02:00
|
|
|
CollectNamedPortals(Portal *portalP, int destroy)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
static Portal *portalList = (Portal *) NULL;
|
|
|
|
static int listIndex = 0;
|
|
|
|
static int maxIndex = 9;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
if (portalList == (Portal *) NULL)
|
|
|
|
portalList = (Portal *) malloc(10 * sizeof(Portal));
|
|
|
|
|
|
|
|
if (destroy != 0)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
int i;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
for (i = 0; i < listIndex; i++)
|
|
|
|
PortalDestroy(&portalList[i]);
|
|
|
|
listIndex = 0;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
1997-09-07 07:04:48 +02:00
|
|
|
else
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
Assert(portalP);
|
|
|
|
Assert(*portalP);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Don't delete special portals, up to portal creator to do this
|
|
|
|
*/
|
|
|
|
if (PortalNameIsSpecial((*portalP)->name))
|
|
|
|
return;
|
|
|
|
|
|
|
|
portalList[listIndex] = *portalP;
|
|
|
|
listIndex++;
|
|
|
|
if (listIndex == maxIndex)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
portalList = (Portal *)
|
|
|
|
realloc(portalList, (maxIndex + 11) * sizeof(Portal));
|
|
|
|
maxIndex += 10;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
}
|
1997-09-07 07:04:48 +02:00
|
|
|
return;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
AtEOXact_portals()
|
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
HashTableWalk(PortalHashTable, CollectNamedPortals, 0);
|
|
|
|
CollectNamedPortals(NULL, 1);
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* PortalDump
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------
|
|
|
|
*/
|
1996-11-08 07:02:30 +01:00
|
|
|
#ifdef NOT_USED
|
1996-07-09 08:22:35 +02:00
|
|
|
static void
|
1997-09-08 23:56:23 +02:00
|
|
|
PortalDump(Portal *thisP)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
/* XXX state/argument checking here */
|
|
|
|
|
|
|
|
PortalVariableMemoryDump(PortalGetVariableMemory(*thisP));
|
|
|
|
PortalHeapMemoryDump(PortalGetHeapMemory(*thisP));
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1996-11-08 07:02:30 +01:00
|
|
|
#endif
|
1996-07-09 08:22:35 +02:00
|
|
|
|
|
|
|
/* ----------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* DumpPortals
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------
|
|
|
|
*/
|
1996-11-08 07:02:30 +01:00
|
|
|
#ifdef NOT_USED
|
1996-07-09 08:22:35 +02:00
|
|
|
static void
|
|
|
|
DumpPortals()
|
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
/* XXX state checking here */
|
|
|
|
|
|
|
|
HashTableWalk(PortalHashTable, PortalDump, 0);
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1996-11-08 07:02:30 +01:00
|
|
|
#endif
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
/* ----------------------------------------------------------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* public portal interface functions
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
* EnablePortalManager --
|
1997-09-07 07:04:48 +02:00
|
|
|
* Enables/disables the portal management module.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
void
|
|
|
|
EnablePortalManager(bool on)
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
static bool processing = false;
|
|
|
|
HASHCTL ctl;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
AssertState(!processing);
|
|
|
|
AssertArg(BoolIsValid(on));
|
|
|
|
|
|
|
|
if (BypassEnable(&PortalManagerEnableCount, on))
|
|
|
|
return;
|
|
|
|
|
|
|
|
processing = true;
|
|
|
|
|
|
|
|
if (on)
|
|
|
|
{ /* initialize */
|
|
|
|
EnableMemoryContext(true);
|
|
|
|
|
|
|
|
PortalMemory = CreateGlobalMemory(PortalMemoryName);
|
|
|
|
|
|
|
|
ctl.keysize = MAX_PORTALNAME_LEN;
|
|
|
|
ctl.datasize = sizeof(Portal);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* use PORTALS_PER_USER, defined in utils/portal.h as a guess of
|
|
|
|
* how many hash table entries to create, initially
|
|
|
|
*/
|
|
|
|
PortalHashTable = hash_create(PORTALS_PER_USER * 3, &ctl, HASH_ELEM);
|
|
|
|
|
|
|
|
CreateNewBlankPortal();
|
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
1997-09-07 07:04:48 +02:00
|
|
|
else
|
|
|
|
{ /* cleanup */
|
|
|
|
if (PortalIsValid(BlankPortal))
|
|
|
|
{
|
|
|
|
PortalDestroy(&BlankPortal);
|
|
|
|
MemoryContextFree((MemoryContext) PortalMemory,
|
|
|
|
(Pointer) BlankPortal);
|
|
|
|
BlankPortal = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Each portal must free its non-memory resources specially.
|
|
|
|
*/
|
|
|
|
HashTableWalk(PortalHashTable, PortalDestroy, 0);
|
|
|
|
hash_destroy(PortalHashTable);
|
|
|
|
PortalHashTable = NULL;
|
|
|
|
|
|
|
|
GlobalMemoryDestroy(PortalMemory);
|
|
|
|
PortalMemory = NULL;
|
|
|
|
|
|
|
|
EnableMemoryContext(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
processing = false;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GetPortalByName --
|
1997-09-07 07:04:48 +02:00
|
|
|
* Returns a portal given a portal name; returns blank portal given
|
1996-07-09 08:22:35 +02:00
|
|
|
* NULL; returns invalid portal if portal not found.
|
|
|
|
*
|
|
|
|
* Exceptions:
|
1997-09-07 07:04:48 +02:00
|
|
|
* BadState if called when disabled.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
Portal
|
|
|
|
GetPortalByName(char *name)
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
Portal portal;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
AssertState(PortalManagerEnabled);
|
|
|
|
|
|
|
|
if (PointerIsValid(name))
|
|
|
|
PortalHashTableLookup(name, portal);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!PortalIsValid(BlankPortal))
|
|
|
|
CreateNewBlankPortal();
|
|
|
|
portal = BlankPortal;
|
|
|
|
}
|
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return portal;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* BlankPortalAssignName --
|
1997-09-07 07:04:48 +02:00
|
|
|
* Returns former blank portal as portal with given name.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Side effect:
|
1997-09-07 07:04:48 +02:00
|
|
|
* All references to the former blank portal become incorrect.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Exceptions:
|
1997-09-07 07:04:48 +02:00
|
|
|
* BadState if called when disabled.
|
|
|
|
* BadState if called without an intervening call to GetPortalByName(NULL).
|
|
|
|
* BadArg if portal name is invalid.
|
|
|
|
* "WARN" if portal name is in use.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
Portal
|
1997-09-07 07:04:48 +02:00
|
|
|
BlankPortalAssignName(char *name) /* XXX PortalName */
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
Portal portal;
|
|
|
|
uint16 length;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
AssertState(PortalManagerEnabled);
|
|
|
|
AssertState(PortalIsValid(BlankPortal));
|
|
|
|
AssertArg(PointerIsValid(name)); /* XXX PortalName */
|
|
|
|
|
|
|
|
portal = GetPortalByName(name);
|
|
|
|
if (PortalIsValid(portal))
|
|
|
|
{
|
|
|
|
elog(NOTICE, "BlankPortalAssignName: portal %s already exists", name);
|
1998-09-01 05:29:17 +02:00
|
|
|
return portal;
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* remove blank portal
|
|
|
|
*/
|
|
|
|
portal = BlankPortal;
|
|
|
|
BlankPortal = NULL;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* initialize portal name
|
|
|
|
*/
|
|
|
|
length = 1 + strlen(name);
|
|
|
|
portal->name = (char *)
|
1997-09-08 23:56:23 +02:00
|
|
|
MemoryContextAlloc((MemoryContext) &portal->variable, length);
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
strncpy(portal->name, name, length);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* put portal in table
|
|
|
|
*/
|
|
|
|
PortalHashTableInsert(portal);
|
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return portal;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* PortalSetQuery --
|
1997-09-07 07:04:48 +02:00
|
|
|
* Attaches a "query" to portal.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Exceptions:
|
1997-09-07 07:04:48 +02:00
|
|
|
* BadState if called when disabled.
|
|
|
|
* BadArg if portal is invalid.
|
|
|
|
* BadArg if queryDesc is "invalid."
|
|
|
|
* BadArg if state is "invalid."
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
void
|
|
|
|
PortalSetQuery(Portal portal,
|
1997-09-08 23:56:23 +02:00
|
|
|
QueryDesc *queryDesc,
|
1997-09-07 07:04:48 +02:00
|
|
|
TupleDesc attinfo,
|
1997-09-08 23:56:23 +02:00
|
|
|
EState *state,
|
1997-09-07 07:04:48 +02:00
|
|
|
void (*cleanup) (Portal portal))
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
AssertState(PortalManagerEnabled);
|
|
|
|
AssertArg(PortalIsValid(portal));
|
|
|
|
AssertArg(IsA((Node *) state, EState));
|
|
|
|
|
|
|
|
portal->queryDesc = queryDesc;
|
|
|
|
portal->state = state;
|
|
|
|
portal->attinfo = attinfo;
|
|
|
|
portal->cleanup = cleanup;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* PortalGetQueryDesc --
|
1997-09-07 07:04:48 +02:00
|
|
|
* Returns query attached to portal.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Exceptions:
|
1997-09-07 07:04:48 +02:00
|
|
|
* BadState if called when disabled.
|
|
|
|
* BadArg if portal is invalid.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1997-09-08 04:41:22 +02:00
|
|
|
QueryDesc *
|
1996-07-09 08:22:35 +02:00
|
|
|
PortalGetQueryDesc(Portal portal)
|
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
AssertState(PortalManagerEnabled);
|
|
|
|
AssertArg(PortalIsValid(portal));
|
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return portal->queryDesc;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* PortalGetState --
|
1997-09-07 07:04:48 +02:00
|
|
|
* Returns state attached to portal.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Exceptions:
|
1997-09-07 07:04:48 +02:00
|
|
|
* BadState if called when disabled.
|
|
|
|
* BadArg if portal is invalid.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1998-02-26 05:46:47 +01:00
|
|
|
EState *
|
1996-07-09 08:22:35 +02:00
|
|
|
PortalGetState(Portal portal)
|
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
AssertState(PortalManagerEnabled);
|
|
|
|
AssertArg(PortalIsValid(portal));
|
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return portal->state;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* CreatePortal --
|
1997-09-07 07:04:48 +02:00
|
|
|
* Returns a new portal given a name.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Note:
|
1997-09-07 07:04:48 +02:00
|
|
|
* This is expected to be of very limited usability. See instead,
|
1996-07-09 08:22:35 +02:00
|
|
|
* BlankPortalAssignName.
|
|
|
|
*
|
|
|
|
* Exceptions:
|
1997-09-07 07:04:48 +02:00
|
|
|
* BadState if called when disabled.
|
|
|
|
* BadArg if portal name is invalid.
|
|
|
|
* "WARN" if portal name is in use.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
Portal
|
1997-09-07 07:04:48 +02:00
|
|
|
CreatePortal(char *name) /* XXX PortalName */
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
Portal portal;
|
|
|
|
uint16 length;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
AssertState(PortalManagerEnabled);
|
|
|
|
AssertArg(PointerIsValid(name)); /* XXX PortalName */
|
|
|
|
|
|
|
|
portal = GetPortalByName(name);
|
|
|
|
if (PortalIsValid(portal))
|
|
|
|
{
|
|
|
|
elog(NOTICE, "CreatePortal: portal %s already exists", name);
|
1998-09-01 05:29:17 +02:00
|
|
|
return portal;
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* make new portal structure */
|
|
|
|
portal = (Portal)
|
|
|
|
MemoryContextAlloc((MemoryContext) PortalMemory, sizeof *portal);
|
|
|
|
|
|
|
|
/* initialize portal variable context */
|
1997-09-08 23:56:23 +02:00
|
|
|
NodeSetTag((Node *) &portal->variable, T_PortalVariableMemory);
|
1997-09-07 07:04:48 +02:00
|
|
|
AllocSetInit(&portal->variable.setData, DynamicAllocMode, (Size) 0);
|
|
|
|
portal->variable.method = &PortalVariableContextMethodsData;
|
|
|
|
|
|
|
|
/* initialize portal heap context */
|
1997-09-08 23:56:23 +02:00
|
|
|
NodeSetTag((Node *) &portal->heap, T_PortalHeapMemory);
|
1997-09-07 07:04:48 +02:00
|
|
|
portal->heap.block = NULL;
|
|
|
|
FixedStackInit(&portal->heap.stackData,
|
|
|
|
offsetof(HeapMemoryBlockData, itemData));
|
|
|
|
portal->heap.method = &PortalHeapContextMethodsData;
|
|
|
|
|
|
|
|
/* initialize portal name */
|
|
|
|
length = 1 + strlen(name);
|
|
|
|
portal->name = (char *)
|
1997-09-08 23:56:23 +02:00
|
|
|
MemoryContextAlloc((MemoryContext) &portal->variable, length);
|
1997-09-07 07:04:48 +02:00
|
|
|
strncpy(portal->name, name, length);
|
|
|
|
|
|
|
|
/* initialize portal query */
|
|
|
|
portal->queryDesc = NULL;
|
|
|
|
portal->attinfo = NULL;
|
|
|
|
portal->state = NULL;
|
|
|
|
portal->cleanup = NULL;
|
|
|
|
|
|
|
|
/* put portal in table */
|
|
|
|
PortalHashTableInsert(portal);
|
|
|
|
|
|
|
|
/* Trap(PointerIsValid(name), Unimplemented); */
|
1998-09-01 05:29:17 +02:00
|
|
|
return portal;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* PortalDestroy --
|
1997-09-07 07:04:48 +02:00
|
|
|
* Destroys portal.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Exceptions:
|
1997-09-07 07:04:48 +02:00
|
|
|
* BadState if called when disabled.
|
|
|
|
* BadArg if portal is invalid.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
void
|
1997-09-08 23:56:23 +02:00
|
|
|
PortalDestroy(Portal *portalP)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
Portal portal = *portalP;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
AssertState(PortalManagerEnabled);
|
|
|
|
AssertArg(PortalIsValid(portal));
|
|
|
|
|
|
|
|
/* remove portal from table if not blank portal */
|
|
|
|
if (portal != BlankPortal)
|
|
|
|
PortalHashTableDelete(portal);
|
|
|
|
|
|
|
|
/* reset portal */
|
|
|
|
if (PointerIsValid(portal->cleanup))
|
|
|
|
(*portal->cleanup) (portal);
|
|
|
|
|
|
|
|
PortalResetHeapMemory(portal);
|
1997-09-08 23:56:23 +02:00
|
|
|
MemoryContextFree((MemoryContext) &portal->variable,
|
1997-09-07 07:04:48 +02:00
|
|
|
(Pointer) portal->name);
|
|
|
|
AllocSetReset(&portal->variable.setData); /* XXX log */
|
|
|
|
|
|
|
|
if (portal != BlankPortal)
|
|
|
|
MemoryContextFree((MemoryContext) PortalMemory, (Pointer) portal);
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* PortalResetHeapMemory --
|
|
|
|
* Resets portal's heap memory context.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Someday, Reset, Start, and End can be optimized by keeping a global
|
|
|
|
* portal module stack of free HeapMemoryBlock's. This will make Start
|
|
|
|
* and End be fast.
|
|
|
|
*
|
|
|
|
* Exceptions:
|
1997-09-07 07:04:48 +02:00
|
|
|
* BadState if called when disabled.
|
|
|
|
* BadState if called when not in PortalHeapMemory context.
|
|
|
|
* BadArg if mode is invalid.
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------
|
|
|
|
*/
|
1997-08-19 23:40:56 +02:00
|
|
|
static void
|
1996-07-09 08:22:35 +02:00
|
|
|
PortalResetHeapMemory(Portal portal)
|
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
PortalHeapMemory context;
|
1997-09-08 04:41:22 +02:00
|
|
|
MemoryContext currentContext;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
context = PortalGetHeapMemory(portal);
|
|
|
|
|
|
|
|
if (PointerIsValid(context->block))
|
|
|
|
{
|
|
|
|
/* save present context */
|
|
|
|
currentContext = MemoryContextSwitchTo((MemoryContext) context);
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
EndPortalAllocMode();
|
|
|
|
} while (PointerIsValid(context->block));
|
|
|
|
|
|
|
|
/* restore context */
|
|
|
|
MemoryContextSwitchTo(currentContext);
|
|
|
|
}
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* StartPortalAllocMode --
|
1997-09-07 07:04:48 +02:00
|
|
|
* Starts a new block of portal heap allocation using mode and limit;
|
|
|
|
* the current block is disabled until EndPortalAllocMode is called.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Note:
|
1997-09-07 07:04:48 +02:00
|
|
|
* Note blocks may be stacked and restored arbitarily.
|
|
|
|
* The semantics of mode and limit are described in aset.h.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Exceptions:
|
1997-09-07 07:04:48 +02:00
|
|
|
* BadState if called when disabled.
|
|
|
|
* BadState if called when not in PortalHeapMemory context.
|
|
|
|
* BadArg if mode is invalid.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
void
|
|
|
|
StartPortalAllocMode(AllocMode mode, Size limit)
|
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
PortalHeapMemory context;
|
|
|
|
|
|
|
|
AssertState(PortalManagerEnabled);
|
|
|
|
AssertState(IsA(CurrentMemoryContext, PortalHeapMemory));
|
|
|
|
/* AssertArg(AllocModeIsValid); */
|
|
|
|
|
|
|
|
context = (PortalHeapMemory) CurrentMemoryContext;
|
|
|
|
|
|
|
|
/* stack current mode */
|
|
|
|
if (PointerIsValid(context->block))
|
|
|
|
FixedStackPush(&context->stackData, context->block);
|
|
|
|
|
|
|
|
/* allocate and initialize new block */
|
|
|
|
context->block =
|
|
|
|
MemoryContextAlloc(
|
|
|
|
(MemoryContext) PortalHeapMemoryGetVariableMemory(context),
|
|
|
|
sizeof(HeapMemoryBlockData));
|
|
|
|
|
|
|
|
/* XXX careful, context->block has never been stacked => bad state */
|
|
|
|
|
|
|
|
AllocSetInit(&HEAPMEMBLOCK(context)->setData, mode, limit);
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* EndPortalAllocMode --
|
1997-09-07 07:04:48 +02:00
|
|
|
* Ends current block of portal heap allocation; previous block is
|
|
|
|
* reenabled.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Note:
|
1997-09-07 07:04:48 +02:00
|
|
|
* Note blocks may be stacked and restored arbitarily.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Exceptions:
|
1997-09-07 07:04:48 +02:00
|
|
|
* BadState if called when disabled.
|
|
|
|
* BadState if called when not in PortalHeapMemory context.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
void
|
|
|
|
EndPortalAllocMode()
|
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
PortalHeapMemory context;
|
|
|
|
|
|
|
|
AssertState(PortalManagerEnabled);
|
|
|
|
AssertState(IsA(CurrentMemoryContext, PortalHeapMemory));
|
|
|
|
|
|
|
|
context = (PortalHeapMemory) CurrentMemoryContext;
|
|
|
|
AssertState(PointerIsValid(context->block)); /* XXX Trap(...) */
|
|
|
|
|
|
|
|
/* free current mode */
|
|
|
|
AllocSetReset(&HEAPMEMBLOCK(context)->setData);
|
|
|
|
MemoryContextFree((MemoryContext) PortalHeapMemoryGetVariableMemory(context),
|
|
|
|
context->block);
|
|
|
|
|
|
|
|
/* restore previous mode */
|
|
|
|
context->block = FixedStackPop(&context->stackData);
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* PortalGetVariableMemory --
|
1997-09-07 07:04:48 +02:00
|
|
|
* Returns variable memory context for a given portal.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Exceptions:
|
1997-09-07 07:04:48 +02:00
|
|
|
* BadState if called when disabled.
|
|
|
|
* BadArg if portal is invalid.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
PortalVariableMemory
|
|
|
|
PortalGetVariableMemory(Portal portal)
|
|
|
|
{
|
1998-09-01 05:29:17 +02:00
|
|
|
return &portal->variable;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* PortalGetHeapMemory --
|
1997-09-07 07:04:48 +02:00
|
|
|
* Returns heap memory context for a given portal.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Exceptions:
|
1997-09-07 07:04:48 +02:00
|
|
|
* BadState if called when disabled.
|
|
|
|
* BadArg if portal is invalid.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
PortalHeapMemory
|
|
|
|
PortalGetHeapMemory(Portal portal)
|
|
|
|
{
|
1998-09-01 05:29:17 +02:00
|
|
|
return &portal->heap;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* PortalVariableMemoryGetPortal --
|
1997-09-07 07:04:48 +02:00
|
|
|
* Returns portal containing given variable memory context.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Exceptions:
|
1997-09-07 07:04:48 +02:00
|
|
|
* BadState if called when disabled.
|
|
|
|
* BadArg if context is invalid.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1997-09-08 04:41:22 +02:00
|
|
|
static Portal
|
1996-07-09 08:22:35 +02:00
|
|
|
PortalVariableMemoryGetPortal(PortalVariableMemory context)
|
|
|
|
{
|
1998-09-01 05:29:17 +02:00
|
|
|
return (Portal) ((char *) context - offsetof(PortalD, variable));
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* PortalHeapMemoryGetPortal --
|
1997-09-07 07:04:48 +02:00
|
|
|
* Returns portal containing given heap memory context.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Exceptions:
|
1997-09-07 07:04:48 +02:00
|
|
|
* BadState if called when disabled.
|
|
|
|
* BadArg if context is invalid.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1997-09-08 04:41:22 +02:00
|
|
|
static Portal
|
1996-07-09 08:22:35 +02:00
|
|
|
PortalHeapMemoryGetPortal(PortalHeapMemory context)
|
|
|
|
{
|
1998-09-01 05:29:17 +02:00
|
|
|
return (Portal) ((char *) context - offsetof(PortalD, heap));
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* PortalVariableMemoryGetHeapMemory --
|
1997-09-07 07:04:48 +02:00
|
|
|
* Returns heap memory context associated with given variable memory.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Exceptions:
|
1997-09-07 07:04:48 +02:00
|
|
|
* BadState if called when disabled.
|
|
|
|
* BadArg if context is invalid.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1997-08-19 23:40:56 +02:00
|
|
|
#ifdef NOT_USED
|
1996-07-09 08:22:35 +02:00
|
|
|
PortalHeapMemory
|
|
|
|
PortalVariableMemoryGetHeapMemory(PortalVariableMemory context)
|
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
return ((PortalHeapMemory) ((char *) context
|
|
|
|
- offsetof(PortalD, variable)
|
1997-09-08 23:56:23 +02:00
|
|
|
+offsetof(PortalD, heap)));
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1997-08-19 23:40:56 +02:00
|
|
|
#endif
|
1996-07-09 08:22:35 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* PortalHeapMemoryGetVariableMemory --
|
1997-09-07 07:04:48 +02:00
|
|
|
* Returns variable memory context associated with given heap memory.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Exceptions:
|
1997-09-07 07:04:48 +02:00
|
|
|
* BadState if called when disabled.
|
|
|
|
* BadArg if context is invalid.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1997-09-08 04:41:22 +02:00
|
|
|
static PortalVariableMemory
|
1996-07-09 08:22:35 +02:00
|
|
|
PortalHeapMemoryGetVariableMemory(PortalHeapMemory context)
|
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
return ((PortalVariableMemory) ((char *) context
|
|
|
|
- offsetof(PortalD, heap)
|
1997-09-08 23:56:23 +02:00
|
|
|
+offsetof(PortalD, variable)));
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|