Skip to content

Commit

Permalink
Add set_user hooks queue
Browse files Browse the repository at this point in the history
Previously, each subsequent hook would overwrite the last. Add a
queueing mechanism, so we can register multiple hooks with set_user.
  • Loading branch information
mpalmi authored and gitstashpop committed Sep 28, 2018
1 parent 70b72d0 commit c7157eb
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 27 deletions.
24 changes: 14 additions & 10 deletions set_user.c
Expand Up @@ -630,19 +630,23 @@ PU_hook(Node *parsetree, const char *queryString,
void
PostSetUserHook(bool is_reset, const char *username)
{
/* Inter-extension hooks */
SetUserHooks **post_hooks;
List **hooks_queue;
ListCell *hooks_entry = NULL;

post_hooks = (SetUserHooks **) find_rendezvous_variable(SET_USER_HOOKS_KEY);
if (*post_hooks)
hooks_queue = (List **) find_rendezvous_variable(SET_USER_HOOKS_KEY);
foreach (hooks_entry, *hooks_queue)
{
if (!is_reset && (*post_hooks)->post_set_user)
SetUserHooks **post_hooks = (SetUserHooks **) lfirst(hooks_entry);
if (post_hooks)
{
(*post_hooks)->post_set_user(username);
}
else if ((*post_hooks)->post_reset_user)
{
(*post_hooks)->post_reset_user();
if (!is_reset && (*post_hooks)->post_set_user)
{
(*post_hooks)->post_set_user(username);
}
else if ((*post_hooks)->post_reset_user)
{
(*post_hooks)->post_reset_user();
}
}
}
}
32 changes: 15 additions & 17 deletions set_user.h
Expand Up @@ -16,27 +16,25 @@ typedef struct SetUserHooks
* set_user hooks.
*
* Takes in two function pointers, which should be defined in the extension.
* Each subsequent call to this function adds a new hook to the queue.
*/
static inline void register_set_user_hooks(void *set_user_hook, void *reset_user_hook)
{
static SetUserHooks **set_user_hooks = NULL;
MemoryContext oldcontext;

/*
* Grab the set user hooks from the rendezvous hash. This should always be
* NULL, unless some other extension has implemented set_user hooks.
*/
set_user_hooks = (SetUserHooks **) find_rendezvous_variable(SET_USER_HOOKS_KEY);

/*
* Populate the hash entry for set_user hooks with extension function
* pointers. These hooks should really only be implemented by one
* extension, so we'll zero out the entry and override, even if non-NULL.
*/
static List **HooksQueue;
static SetUserHooks *next_hook_entry = NULL;
MemoryContext oldcontext;

oldcontext = MemoryContextSwitchTo(TopMemoryContext);
*set_user_hooks = palloc0(sizeof(SetUserHooks));
(*set_user_hooks)->post_set_user = set_user_hook;
(*set_user_hooks)->post_reset_user = reset_user_hook;

/* Grab the SetUserHooks queue from the rendezvous hash */
HooksQueue = (List **) find_rendezvous_variable(SET_USER_HOOKS_KEY);

/* Populate a new hooks entry and append it to the queue */
next_hook_entry = palloc0(sizeof(SetUserHooks));
next_hook_entry->post_set_user = set_user_hook;
next_hook_entry->post_reset_user = reset_user_hook;

*HooksQueue = lappend(*HooksQueue, &next_hook_entry);
MemoryContextSwitchTo(oldcontext);
}

Expand Down

0 comments on commit c7157eb

Please sign in to comment.