📄 portalmem.c
字号:
{ static bool processing = false; HASHCTL ctl; 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(); } 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;}/* * GetPortalByName * Returns a portal given a portal name; returns blank portal given * NULL; returns invalid portal if portal not found. * * Exceptions: * BadState if called when disabled. */PortalGetPortalByName(char *name){ Portal portal; AssertState(PortalManagerEnabled); if (PointerIsValid(name)) PortalHashTableLookup(name, portal); else { if (!PortalIsValid(BlankPortal)) CreateNewBlankPortal(); portal = BlankPortal; } return portal;}/* * BlankPortalAssignName * Returns former blank portal as portal with given name. * * Side effect: * All references to the former blank portal become incorrect. * * Exceptions: * 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. */PortalBlankPortalAssignName(char *name) /* XXX PortalName */{ Portal portal; uint16 length; AssertState(PortalManagerEnabled); AssertState(PortalIsValid(BlankPortal)); AssertArg(PointerIsValid(name)); /* XXX PortalName */ portal = GetPortalByName(name); if (PortalIsValid(portal)) { elog(NOTICE, "BlankPortalAssignName: portal %s already exists", name); return portal; } /* * remove blank portal */ portal = BlankPortal; BlankPortal = NULL; /* * initialize portal name */ length = 1 + strlen(name); portal->name = (char *) MemoryContextAlloc((MemoryContext) &portal->variable, length); strncpy(portal->name, name, length); /* * put portal in table */ PortalHashTableInsert(portal); return portal;}/* * PortalSetQuery * Attaches a "query" to portal. * * Exceptions: * BadState if called when disabled. * BadArg if portal is invalid. * BadArg if queryDesc is "invalid." * BadArg if state is "invalid." */voidPortalSetQuery(Portal portal, QueryDesc *queryDesc, TupleDesc attinfo, EState *state, void (*cleanup) (Portal portal)){ AssertState(PortalManagerEnabled); AssertArg(PortalIsValid(portal)); AssertArg(IsA((Node *) state, EState)); portal->queryDesc = queryDesc; portal->state = state; portal->attinfo = attinfo; portal->cleanup = cleanup;}/* * PortalGetQueryDesc * Returns query attached to portal. * * Exceptions: * BadState if called when disabled. * BadArg if portal is invalid. */QueryDesc *PortalGetQueryDesc(Portal portal){ AssertState(PortalManagerEnabled); AssertArg(PortalIsValid(portal)); return portal->queryDesc;}/* * PortalGetState * Returns state attached to portal. * * Exceptions: * BadState if called when disabled. * BadArg if portal is invalid. */EState *PortalGetState(Portal portal){ AssertState(PortalManagerEnabled); AssertArg(PortalIsValid(portal)); return portal->state;}/* * CreatePortal * Returns a new portal given a name. * * Note: * This is expected to be of very limited usability. See instead, * BlankPortalAssignName. * * Exceptions: * BadState if called when disabled. * BadArg if portal name is invalid. * "WARN" if portal name is in use. */PortalCreatePortal(char *name) /* XXX PortalName */{ Portal portal; uint16 length; AssertState(PortalManagerEnabled); AssertArg(PointerIsValid(name)); /* XXX PortalName */ portal = GetPortalByName(name); if (PortalIsValid(portal)) { elog(NOTICE, "CreatePortal: portal %s already exists", name); return portal; } /* make new portal structure */ portal = (Portal) MemoryContextAlloc((MemoryContext) PortalMemory, sizeof *portal); /* initialize portal variable context */ NodeSetTag((Node *) &portal->variable, T_PortalVariableMemory); AllocSetInit(&portal->variable.setData, DynamicAllocMode, (Size) 0); portal->variable.method = &PortalVariableContextMethodsData; /* initialize portal heap context */ NodeSetTag((Node *) &portal->heap, T_PortalHeapMemory); 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 *) MemoryContextAlloc((MemoryContext) &portal->variable, length); 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); */ return portal;}/* * PortalDestroy * Destroys portal. * * Exceptions: * BadState if called when disabled. * BadArg if portal is invalid. */voidPortalDestroy(Portal *portalP){ Portal portal = *portalP; 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); MemoryContextFree((MemoryContext) &portal->variable, (Pointer) portal->name); AllocSetReset(&portal->variable.setData); /* XXX log */ /* * In the case of a transaction abort it is possible that we get * called while one of the memory contexts of the portal we're * destroying is the current memory context. * * Don't know how to handle that cleanly because it is required to be in * that context right now. This portal struct remains allocated in the * PortalMemory context until backend dies. * * Not happy with that, but it's better to loose some bytes of memory * than to have the backend dump core. * * --- Feb. 04, 1999 Jan Wieck */ if (CurrentMemoryContext == (MemoryContext) PortalGetHeapMemory(portal)) return; if (CurrentMemoryContext == (MemoryContext) PortalGetVariableMemory(portal)) return; if (portal != BlankPortal) MemoryContextFree((MemoryContext) PortalMemory, (Pointer) portal);}/* ---------------- * PortalResetHeapMemory * Resets portal's heap memory context. * * 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: * BadState if called when disabled. * BadState if called when not in PortalHeapMemory context. * BadArg if mode is invalid. * ---------------- */voidPortalResetHeapMemory(Portal portal){ PortalHeapMemory context; MemoryContext currentContext; context = PortalGetHeapMemory(portal); if (PointerIsValid(context->block)) { /* save present context */ currentContext = MemoryContextSwitchTo((MemoryContext) context); do { EndPortalAllocMode(); } while (PointerIsValid(context->block)); /* restore context */ MemoryContextSwitchTo(currentContext); }}/* * StartPortalAllocMode * Starts a new block of portal heap allocation using mode and limit; * the current block is disabled until EndPortalAllocMode is called. * * Note: * Note blocks may be stacked and restored arbitarily. * The semantics of mode and limit are described in aset.h. * * Exceptions: * BadState if called when disabled. * BadState if called when not in PortalHeapMemory context. * BadArg if mode is invalid. */voidStartPortalAllocMode(AllocMode mode, Size limit){ 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);}/* * EndPortalAllocMode * Ends current block of portal heap allocation; previous block is * reenabled. * * Note: * Note blocks may be stacked and restored arbitarily. * * Exceptions: * BadState if called when disabled. * BadState if called when not in PortalHeapMemory context. */voidEndPortalAllocMode(){ 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);}/* * PortalGetVariableMemory * Returns variable memory context for a given portal. * * Exceptions: * BadState if called when disabled. * BadArg if portal is invalid. */PortalVariableMemoryPortalGetVariableMemory(Portal portal){ return &portal->variable;}/* * PortalGetHeapMemory * Returns heap memory context for a given portal. * * Exceptions: * BadState if called when disabled. * BadArg if portal is invalid. */PortalHeapMemoryPortalGetHeapMemory(Portal portal){ return &portal->heap;}/* * PortalVariableMemoryGetPortal * Returns portal containing given variable memory context. * * Exceptions: * BadState if called when disabled. * BadArg if context is invalid. */static PortalPortalVariableMemoryGetPortal(PortalVariableMemory context){ return (Portal) ((char *) context - offsetof(PortalD, variable));}/* * PortalHeapMemoryGetPortal * Returns portal containing given heap memory context. * * Exceptions: * BadState if called when disabled. * BadArg if context is invalid. */static PortalPortalHeapMemoryGetPortal(PortalHeapMemory context){ return (Portal) ((char *) context - offsetof(PortalD, heap));}/* * PortalVariableMemoryGetHeapMemory * Returns heap memory context associated with given variable memory. * * Exceptions: * BadState if called when disabled. * BadArg if context is invalid. */#ifdef NOT_USEDPortalHeapMemoryPortalVariableMemoryGetHeapMemory(PortalVariableMemory context){ return ((PortalHeapMemory) ((char *) context - offsetof(PortalD, variable) +offsetof(PortalD, heap)));}#endif/* * PortalHeapMemoryGetVariableMemory * Returns variable memory context associated with given heap memory. * * Exceptions: * BadState if called when disabled. * BadArg if context is invalid. */static PortalVariableMemoryPortalHeapMemoryGetVariableMemory(PortalHeapMemory context){ return ((PortalVariableMemory) ((char *) context - offsetof(PortalD, heap) +offsetof(PortalD, variable)));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -