Merge pull request #321 from edk0/hook-priorities

Simple hook priority system
This commit is contained in:
Aaron Jones 2020-06-10 14:49:59 +00:00 committed by GitHub
commit 64e6d3b9cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 68 additions and 13 deletions

View file

@ -13,7 +13,7 @@ static void m_invited(struct MsgBuf *, struct Client *, struct Client *, int, co
static unsigned int CAP_INVITE_NOTIFY;
mapi_hfn_list_av1 inv_notify_hfnlist[] = {
{ "invite", hook_invite },
{ "invite", hook_invite, HOOK_MONITOR },
{ NULL, NULL }
};

View file

@ -66,7 +66,8 @@ mapi_clist_av1 webirc_clist[] = { &webirc_msgtab, NULL };
static void new_local_user(void *data);
mapi_hfn_list_av1 webirc_hfnlist[] = {
{ "new_local_user", (hookfn) new_local_user },
/* unintuitive but correct--we want to be called first */
{ "new_local_user", (hookfn) new_local_user, HOOK_LOWEST },
{ NULL, NULL }
};

View file

@ -34,10 +34,10 @@ static void handle_client_exit(void *data);
mapi_hfn_list_av1 override_hfnlist[] = {
{ "umode_changed", (hookfn) check_umode_change },
{ "get_channel_access", (hookfn) hack_channel_access },
{ "can_join", (hookfn) hack_can_join },
{ "can_kick", (hookfn) hack_can_kick },
{ "can_send", (hookfn) hack_can_send },
{ "get_channel_access", (hookfn) hack_channel_access, HOOK_HIGHEST },
{ "can_join", (hookfn) hack_can_join, HOOK_HIGHEST },
{ "can_kick", (hookfn) hack_can_kick, HOOK_HIGHEST },
{ "can_send", (hookfn) hack_can_send, HOOK_HIGHEST },
{ "client_exit", (hookfn) handle_client_exit },
{ NULL, NULL }
};

View file

@ -14,7 +14,7 @@ static const char override_kick_immunity_desc[] =
static void can_kick(void *data);
mapi_hfn_list_av1 override_kick_immunity_hfnlist[] = {
{ "can_kick", (hookfn) can_kick },
{ "can_kick", (hookfn) can_kick, HOOK_HIGHEST },
{ NULL, NULL }
};

View file

@ -11,6 +11,16 @@ typedef struct
rb_dlink_list hooks;
} hook;
enum hook_priority
{
HOOK_LOWEST = 10,
HOOK_LOW = 20,
HOOK_NORMAL = 30,
HOOK_HIGH = 40,
HOOK_HIGHEST = 50,
HOOK_MONITOR = 100
};
typedef void (*hookfn) (void *data);
extern int h_iosend_id;
@ -39,6 +49,7 @@ extern int h_rehash;
void init_hook(void);
int register_hook(const char *name);
void add_hook(const char *name, hookfn fn);
void add_hook_prio(const char *name, hookfn fn, enum hook_priority priority);
void remove_hook(const char *name, hookfn fn);
void call_hook(int id, void *arg);

View file

@ -70,9 +70,9 @@ typedef struct
{
const char *hapi_name;
hookfn fn;
enum hook_priority priority;
} mapi_hfn_list_av1;
#define MAPI_CAP_CLIENT 1
#define MAPI_CAP_SERVER 2

View file

@ -42,6 +42,13 @@ hook *hooks;
#define HOOK_INCREMENT 1000
struct hook_entry
{
rb_dlink_node node;
hookfn fn;
enum hook_priority priority;
};
int num_hooks = 0;
int last_hook = 0;
int max_hooks = HOOK_INCREMENT;
@ -174,11 +181,34 @@ register_hook(const char *name)
void
add_hook(const char *name, hookfn fn)
{
add_hook_prio(name, fn, HOOK_NORMAL);
}
/* add_hook_prio()
* Adds a hook with the specified priority
*/
void
add_hook_prio(const char *name, hookfn fn, enum hook_priority priority)
{
rb_dlink_node *ptr;
struct hook_entry *entry = rb_malloc(sizeof *entry);
int i;
i = register_hook(name);
entry->fn = fn;
entry->priority = priority;
rb_dlinkAddAlloc(fn, &hooks[i].hooks);
RB_DLINK_FOREACH(ptr, hooks[i].hooks.head)
{
struct hook_entry *o = ptr->data;
if (entry->priority <= o->priority)
{
rb_dlinkAddBefore(ptr, entry, &entry->node, &hooks[i].hooks);
return;
}
}
rb_dlinkAddTail(entry, &entry->node, &hooks[i].hooks);
}
/* remove_hook()
@ -187,12 +217,21 @@ add_hook(const char *name, hookfn fn)
void
remove_hook(const char *name, hookfn fn)
{
rb_dlink_node *ptr, *scratch;
int i;
if((i = find_hook(name)) < 0)
return;
rb_dlinkFindDestroy(fn, &hooks[i].hooks);
RB_DLINK_FOREACH_SAFE(ptr, scratch, hooks[i].hooks.head)
{
struct hook_entry *entry = ptr->data;
if (entry->fn == fn)
{
rb_dlinkDelete(ptr, &hooks[i].hooks);
return;
}
}
}
/* call_hook()
@ -201,7 +240,6 @@ remove_hook(const char *name, hookfn fn)
void
call_hook(int id, void *arg)
{
hookfn fn;
rb_dlink_node *ptr;
/* The ID we were passed is the position in the hook table of this
@ -209,8 +247,8 @@ call_hook(int id, void *arg)
*/
RB_DLINK_FOREACH(ptr, hooks[id].hooks.head)
{
fn = ptr->data;
fn(arg);
struct hook_entry *entry = ptr->data;
entry->fn(arg);
}
}

View file

@ -586,8 +586,13 @@ load_a_module(const char *path, bool warn, int origin, bool core)
{
mapi_hfn_list_av1 *m;
for (m = mheader->mapi_hfn_list; m->hapi_name; ++m)
{
int priority = m->priority;
if (priority == 0)
priority = HOOK_NORMAL;
add_hook(m->hapi_name, m->fn);
}
}
/* New in MAPI v2 - version replacement */
ver = mheader->mapi_module_version ? mheader->mapi_module_version : ircd_version;