MemoryContext reset/delete callbacks

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: pgsql-hackers(at)postgreSQL(dot)org
Subject: MemoryContext reset/delete callbacks
Date: 2015-02-27 00:28:50
Message-ID: 6804.1424996930@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

We discussed this idea a couple weeks ago. The core of it is that when a
memory context is being deleted, you might want something extra to happen
beyond just pfree'ing everything in the context. I'm thinking in
particular that this might provide a nice solution to the problem we
discussed earlier today of managing cached information about a domain's
CHECK constraints: a function could make a reference-counted link to some
data in its FmgrInfo cache, and use a memory context callback on the
context containing the FmgrInfo to ensure that the reference count gets
decremented when needed and not before.

Attached is a draft patch for this. I've not really tested it more than
seeing that it compiles, but it's so simple that there are unlikely to be
bugs as such in it. There are some design decisions that could be
questioned though:

1. I used ilists for the linked list of callback requests. This creates a
dependency from memory contexts to lib/ilist. That's all right at the
moment since lib/ilist does no memory allocation, but it might be
logically problematic. We could just use explicit "struct foo *" links
with little if any notational penalty, so I wonder if that would be
better.

2. I specified that callers have to allocate the storage for the callback
structs. This saves a palloc cycle in just about every use-case I've
thought of, since callers generally will need to palloc some larger struct
of their own and they can just embed the MemoryContextCallback struct in
that. It does seem like this offers a larger surface for screwups, in
particular putting the callback struct in the wrong memory context --- but
there's plenty of surface for that type of mistake anyway, if you put
whatever the "void *arg" is pointing at in the wrong context.
So I'm OK with this but could also accept a design in which
MemoryContextRegisterResetCallback takes just a function pointer and a
"void *arg" and palloc's the callback struct for itself in the target
context. I'm unsure whether that adds enough safety to justify a separate
palloc.

3. Is the "void *arg" API for the callback func sufficient? I considered
also passing it the MemoryContext, but couldn't really find a use-case
to justify that.

4. I intentionally didn't provide a MemoryContextDeregisterResetCallback
API. Since it's just a singly-linked list, that could be an expensive
operation and so I'd rather discourage it. In the use cases I've thought
of, you'd want the callback to remain active for the life of the context
anyway, so there would be no need. (And, of course, there is slist_delete
for the truly determined ...)

Comments?

regards, tom lane

Attachment Content-Type Size
memory-context-callbacks-1.0.patch text/x-diff 6.4 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Amit Langote 2015-02-27 00:29:04 Re: Partitioning WIP patch
Previous Message Amit Langote 2015-02-27 00:09:35 Re: Partitioning WIP patch