Merge pull request #321 from edk0/hook-priorities
Simple hook priority system
This commit is contained in:
commit
64e6d3b9cd
8 changed files with 68 additions and 13 deletions
|
@ -13,7 +13,7 @@ static void m_invited(struct MsgBuf *, struct Client *, struct Client *, int, co
|
||||||
static unsigned int CAP_INVITE_NOTIFY;
|
static unsigned int CAP_INVITE_NOTIFY;
|
||||||
|
|
||||||
mapi_hfn_list_av1 inv_notify_hfnlist[] = {
|
mapi_hfn_list_av1 inv_notify_hfnlist[] = {
|
||||||
{ "invite", hook_invite },
|
{ "invite", hook_invite, HOOK_MONITOR },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,8 @@ mapi_clist_av1 webirc_clist[] = { &webirc_msgtab, NULL };
|
||||||
|
|
||||||
static void new_local_user(void *data);
|
static void new_local_user(void *data);
|
||||||
mapi_hfn_list_av1 webirc_hfnlist[] = {
|
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 }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -34,10 +34,10 @@ static void handle_client_exit(void *data);
|
||||||
|
|
||||||
mapi_hfn_list_av1 override_hfnlist[] = {
|
mapi_hfn_list_av1 override_hfnlist[] = {
|
||||||
{ "umode_changed", (hookfn) check_umode_change },
|
{ "umode_changed", (hookfn) check_umode_change },
|
||||||
{ "get_channel_access", (hookfn) hack_channel_access },
|
{ "get_channel_access", (hookfn) hack_channel_access, HOOK_HIGHEST },
|
||||||
{ "can_join", (hookfn) hack_can_join },
|
{ "can_join", (hookfn) hack_can_join, HOOK_HIGHEST },
|
||||||
{ "can_kick", (hookfn) hack_can_kick },
|
{ "can_kick", (hookfn) hack_can_kick, HOOK_HIGHEST },
|
||||||
{ "can_send", (hookfn) hack_can_send },
|
{ "can_send", (hookfn) hack_can_send, HOOK_HIGHEST },
|
||||||
{ "client_exit", (hookfn) handle_client_exit },
|
{ "client_exit", (hookfn) handle_client_exit },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,7 +14,7 @@ static const char override_kick_immunity_desc[] =
|
||||||
static void can_kick(void *data);
|
static void can_kick(void *data);
|
||||||
|
|
||||||
mapi_hfn_list_av1 override_kick_immunity_hfnlist[] = {
|
mapi_hfn_list_av1 override_kick_immunity_hfnlist[] = {
|
||||||
{ "can_kick", (hookfn) can_kick },
|
{ "can_kick", (hookfn) can_kick, HOOK_HIGHEST },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,16 @@ typedef struct
|
||||||
rb_dlink_list hooks;
|
rb_dlink_list hooks;
|
||||||
} hook;
|
} 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);
|
typedef void (*hookfn) (void *data);
|
||||||
|
|
||||||
extern int h_iosend_id;
|
extern int h_iosend_id;
|
||||||
|
@ -39,6 +49,7 @@ extern int h_rehash;
|
||||||
void init_hook(void);
|
void init_hook(void);
|
||||||
int register_hook(const char *name);
|
int register_hook(const char *name);
|
||||||
void add_hook(const char *name, hookfn fn);
|
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 remove_hook(const char *name, hookfn fn);
|
||||||
void call_hook(int id, void *arg);
|
void call_hook(int id, void *arg);
|
||||||
|
|
||||||
|
|
|
@ -70,9 +70,9 @@ typedef struct
|
||||||
{
|
{
|
||||||
const char *hapi_name;
|
const char *hapi_name;
|
||||||
hookfn fn;
|
hookfn fn;
|
||||||
|
enum hook_priority priority;
|
||||||
} mapi_hfn_list_av1;
|
} mapi_hfn_list_av1;
|
||||||
|
|
||||||
|
|
||||||
#define MAPI_CAP_CLIENT 1
|
#define MAPI_CAP_CLIENT 1
|
||||||
#define MAPI_CAP_SERVER 2
|
#define MAPI_CAP_SERVER 2
|
||||||
|
|
||||||
|
|
48
ircd/hook.c
48
ircd/hook.c
|
@ -42,6 +42,13 @@ hook *hooks;
|
||||||
|
|
||||||
#define HOOK_INCREMENT 1000
|
#define HOOK_INCREMENT 1000
|
||||||
|
|
||||||
|
struct hook_entry
|
||||||
|
{
|
||||||
|
rb_dlink_node node;
|
||||||
|
hookfn fn;
|
||||||
|
enum hook_priority priority;
|
||||||
|
};
|
||||||
|
|
||||||
int num_hooks = 0;
|
int num_hooks = 0;
|
||||||
int last_hook = 0;
|
int last_hook = 0;
|
||||||
int max_hooks = HOOK_INCREMENT;
|
int max_hooks = HOOK_INCREMENT;
|
||||||
|
@ -174,11 +181,34 @@ register_hook(const char *name)
|
||||||
void
|
void
|
||||||
add_hook(const char *name, hookfn fn)
|
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;
|
int i;
|
||||||
|
|
||||||
i = register_hook(name);
|
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()
|
/* remove_hook()
|
||||||
|
@ -187,12 +217,21 @@ add_hook(const char *name, hookfn fn)
|
||||||
void
|
void
|
||||||
remove_hook(const char *name, hookfn fn)
|
remove_hook(const char *name, hookfn fn)
|
||||||
{
|
{
|
||||||
|
rb_dlink_node *ptr, *scratch;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if((i = find_hook(name)) < 0)
|
if((i = find_hook(name)) < 0)
|
||||||
return;
|
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()
|
/* call_hook()
|
||||||
|
@ -201,7 +240,6 @@ remove_hook(const char *name, hookfn fn)
|
||||||
void
|
void
|
||||||
call_hook(int id, void *arg)
|
call_hook(int id, void *arg)
|
||||||
{
|
{
|
||||||
hookfn fn;
|
|
||||||
rb_dlink_node *ptr;
|
rb_dlink_node *ptr;
|
||||||
|
|
||||||
/* The ID we were passed is the position in the hook table of this
|
/* 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)
|
RB_DLINK_FOREACH(ptr, hooks[id].hooks.head)
|
||||||
{
|
{
|
||||||
fn = ptr->data;
|
struct hook_entry *entry = ptr->data;
|
||||||
fn(arg);
|
entry->fn(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -586,8 +586,13 @@ load_a_module(const char *path, bool warn, int origin, bool core)
|
||||||
{
|
{
|
||||||
mapi_hfn_list_av1 *m;
|
mapi_hfn_list_av1 *m;
|
||||||
for (m = mheader->mapi_hfn_list; m->hapi_name; ++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);
|
add_hook(m->hapi_name, m->fn);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* New in MAPI v2 - version replacement */
|
/* New in MAPI v2 - version replacement */
|
||||||
ver = mheader->mapi_module_version ? mheader->mapi_module_version : ircd_version;
|
ver = mheader->mapi_module_version ? mheader->mapi_module_version : ircd_version;
|
||||||
|
|
Loading…
Reference in a new issue