[−][src]Enum pgx::memcxt::PgMemoryContexts
An Enumeration of Postgres top-level MemoryContexts. Each have their own use and "lifetimes" as defined by Postgres' memory management model.
It's possible to deference any one of these (except Transient
) via the ::value()
method if
it's necessary to pass the raw pointer to a Postgres function.
Additionally, the ::switch_to()
function, which takes a closure as its argument, executes the
closure within that MemoryContext
Variants
Because it would be too much notational overhead to always pass an appropriate memory context to called routines, there always exists the notion of the current memory context CurrentMemoryContext. Without it, for example, the copyObject routines would need to be passed a context, as would function execution routines that return a pass-by-reference datatype. Similarly for routines that temporarily allocate space internally, but don't return it to their caller? We certainly don't want to clutter every call in the system with "here is a context to use for any temporary memory allocation you might want to do".
The upshot of that reasoning, though, is that CurrentMemoryContext should generally point at a short-lifespan context if at all possible. During query execution it usually points to a context that gets reset after each tuple. Only in very circumscribed code should it ever point at a context having greater than transaction lifespan, since doing so risks permanent memory leaks.
this is the actual top level of the context tree; every other context is a direct or indirect child of this one. Allocating here is essentially the same as "malloc", because this context will never be reset or deleted. This is for stuff that should live forever, or for stuff that the controlling module will take care of deleting at the appropriate time. An example is fd.c's tables of open files. Avoid allocating stuff here unless really necessary, and especially avoid running with CurrentMemoryContext pointing here.
this is not actually a separate context, but a global variable pointing to the per-portal context of the currently active execution portal. This can be used if it's necessary to allocate storage that will live just as long as the execution of the current portal requires.
this permanent context is switched into for error recovery processing, and then reset on completion of recovery. We arrange to have a few KB of memory available in it at all times. In this way, we can ensure that some memory is available for error recovery even if the backend has run out of memory otherwise. This allows out-of-memory to be treated as a normal ERROR condition, not a FATAL error.
this is the postmaster's normal working context. After a backend is spawned, it can delete PostmasterContext to free its copy of memory the postmaster was using that it doesn't need. Note that in non-EXEC_BACKEND builds, the postmaster's copy of pg_hba.conf and pg_ident.conf data is used directly during authentication in backend processes; so backends can't delete PostmasterContext until that's done. (The postmaster has only TopMemoryContext, PostmasterContext, and ErrorContext --- the remaining top-level contexts are set up in each backend during startup.)
permanent storage for relcache, catcache, and related modules. This will never be reset or deleted, either, so it's not truly necessary to distinguish it from TopMemoryContext. But it seems worthwhile to maintain the distinction for debugging purposes. (Note: CacheMemoryContext has child contexts with shorter lifespans. For example, a child context is the best place to keep the subsidiary storage associated with a relcache entry; that way we can free rule parsetrees and so forth easily, without having to depend on constructing a reliable version of freeObject().)
this context holds the current command message from the frontend, as well as any derived storage that need only live as long as the current message (for example, in simple-Query mode the parse and plan trees can live here). This context will be reset, and any children deleted, at the top of each cycle of the outer loop of PostgresMain. This is kept separate from per-transaction and per-portal contexts because a query string might need to live either a longer or shorter time than any single transaction or portal.
this holds everything that lives until end of the top-level transaction. This context will be reset, and all its children deleted, at conclusion of each top-level transaction cycle. In most cases you don't want to allocate stuff directly here, but in CurTransactionContext; what does belong here is control information that exists explicitly to manage status across multiple subtransactions. Note: this context is NOT cleared immediately upon error; its contents will survive until the transaction block is exited by COMMIT/ROLLBACK.
this holds data that has to survive until the end of the current transaction, and in particular will be needed at top-level transaction commit. When we are in a top-level transaction this is the same as TopTransactionContext, but in subtransactions it points to a child context. It is important to understand that if a subtransaction aborts, its CurTransactionContext is thrown away after finishing the abort processing; but a committed subtransaction's CurTransactionContext is kept until top-level commit (unless of course one of the intermediate levels of subtransaction aborts). This ensures that we do not keep data from a failed subtransaction longer than necessary. Because of this behavior, you must be careful to clean up properly during subtransaction abort --- the subtransaction's state must be delinked from any pointers or lists kept in upper transactions, or you will have dangling pointers leading to a crash at top-level commit. An example of data kept here is pending NOTIFY messages, which are sent at top-level commit, but only if the generating subtransaction did not abort.
For(MemoryContext)
This represents a MemoryContext that was likely created via pg_sys::AllocSetContextCreateExtended.
That could be a MemoryContext you created yourself, or it could be one given to you from
Postgres. For example, the TupleTableSlot
struct has a field referencing the MemoryContext
in which slots are allocated.
Owned(OwnedMemoryContext)
A MemoryContext owned by Rust that will be freed when when Dropped
Of(void_ptr)
Use the MemoryContext in which the specified pointer was allocated.
It's incredibly important that the specified pointer be one actually allocated by Postgres' memory management system. Otherwise, it's undefined behavior and will absolutely crash Postgres
Create a temporary MemoryContext for use with [::switch_to()]. It gets deleted as soon as [::switch_to()] exits.
Trying to use this context through [::value{}] will result in a panic!().
Fields of Transient
parent: MemoryContext
name: &'static str
min_context_size: u32
initial_block_size: u32
max_block_size: u32
Implementations
impl PgMemoryContexts
[src]
pub fn new(name: &str) -> PgMemoryContexts
[src]
Create a new PgMemoryContext::Owned
pub fn value(&self) -> MemoryContext
[src]
Retrieve the underlying Postgres *mut MemoryContextData
This works for every type except the ::Transient
type.
pub fn set_as_current(&self) -> PgMemoryContexts
[src]
Set this MemoryContext as the CurrentMemoryContext, returning whatever
CurrentMemoryContext` is
pub fn reset(&mut self)
[src]
Release all space allocated within a context and delete all its descendant contexts (but not the context itself).
pub fn switch_to<R, F: Fn(&mut PgMemoryContexts) -> R + UnwindSafe + RefUnwindSafe>(
&mut self,
f: F
) -> R
[src]
&mut self,
f: F
) -> R
Run the specified function "within" the MemoryContext
represented by this enum.
The important implementation detail is that Postgres' CurrentMemoryContext
is changed
to be this context, the function is run so that all Postgres memory allocations happen
within that context, and then CurrentMemoryContext
is restored to what it was before
we started.
Examples
use pgx::*; #[pg_guard] pub fn do_something() -> pg_sys::ItemPointer { PgMemoryContexts::TopTransactionContext.switch_to(|context| { // allocate a new ItemPointerData, but inside the TopTransactionContext let tid = PgBox::<pg_sys::ItemPointerData>::alloc(); // do something with the tid and then return it. // Note that it stays allocated here in the TopTransactionContext tid.into_pg() }) }
pub fn pstrdup(&self, s: &str) -> *mut c_char
[src]
Duplicate a Rust &str
into a Postgres-allocated "char *"
Examples
use pgx::PgMemoryContexts; let copy = PgMemoryContexts::CurrentMemoryContext.pstrdup("make a copy of this");
pub fn copy_ptr_into<T>(&mut self, src: *mut T, len: usize) -> *mut T
[src]
Copies len
bytes, starting at src
into this memory context and
returns a raw *mut T
pointer to the newly allocated location
pub fn palloc(&mut self, len: usize) -> *mut c_void
[src]
Allocate memory in this context, which will be free'd whenever Postgres deletes this MemoryContext
pub fn palloc_struct<T>(&mut self) -> *mut T
[src]
pub fn palloc0_struct<T>(&mut self) -> *mut T
[src]
pub fn palloc_slice<'a, T>(&mut self, len: usize) -> &'a mut [T]
[src]
Allocate a slice in this context, which will be free'd whenever Postgres deletes this MemoryContext
pub fn palloc0_slice<'a, T>(&mut self, len: usize) -> &'a mut [T]
[src]
Allocate a slice in this context, where the memory is zero'd, which will be free'd whenever Postgres deletes this MemoryContext
pub fn palloc0(&mut self, len: usize) -> *mut c_void
[src]
Allocate memory in this context, which will be free'd whenever Postgres deletes this MemoryContext
The allocated memory is zero'd
pub fn leak_and_drop_on_delete<T>(&mut self, v: T) -> *mut T
[src]
Trait Implementations
Auto Trait Implementations
impl RefUnwindSafe for PgMemoryContexts
[src]
impl !Send for PgMemoryContexts
[src]
impl !Sync for PgMemoryContexts
[src]
impl Unpin for PgMemoryContexts
[src]
impl UnwindSafe for PgMemoryContexts
[src]
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> Same<T> for T
type Output = T
Should always be Self
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,