Official timeout routines for netgraph nodes that know how to

use (and abuse) the node locking system.

MFC after:	1 week
This commit is contained in:
Julian Elischer 2002-03-05 20:26:20 +00:00
parent 89e1164ee2
commit d2ca21a9b2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=91711
2 changed files with 66 additions and 0 deletions

View file

@ -1127,6 +1127,10 @@ int ng_rmtype(struct ng_type *tp);
int ng_snd_item(item_p item, int queue);
int ng_send_fn(node_p node, hook_p hook, ng_item_fn *fn,
void *arg1, int arg2);
int ng_untimeout(struct callout_handle handle, node_p node);
struct callout_handle
ng_timeout(node_p node, hook_p hook, int ticks,
ng_item_fn *fn, void * arg1, int arg2);
/*
* prototypes the user should DEFINITLY not use directly

View file

@ -3617,6 +3617,68 @@ ng_send_fn(node_p node, hook_p hook, ng_item_fn *fn, void * arg1, int arg2)
return(ng_snd_item(item, 0));
}
/*
* Official timeout routines for Netgraph nodes.
*/
static void
ng_timeout_trapoline(void *arg)
{
item_p item = arg;
ng_snd_item(item, 0);
}
struct callout_handle
ng_timeout(node_p node, hook_p hook, int ticks,
ng_item_fn *fn, void * arg1, int arg2)
{
item_p item;
if ((item = ng_getqblk()) == NULL) {
struct callout_handle handle;
handle.callout = NULL;
return (handle);
}
item->el_flags = NGQF_FN | NGQF_WRITER;
NG_NODE_REF(node); /* and one for the item */
NGI_SET_NODE(item, node);
if (hook) {
NG_HOOK_REF(hook);
NGI_SET_HOOK(item, hook);
}
NGI_FN(item) = fn;
NGI_ARG1(item) = arg1;
NGI_ARG2(item) = arg2;
return (timeout(&ng_timeout_trapoline, item, ticks));
}
/* A special modified version of untimeout() */
int
ng_untimeout(struct callout_handle handle, node_p node)
{
item_p item;
if (handle.callout == NULL)
return (0);
mtx_lock_spin(&callout_lock);
item = handle.callout->c_arg; /* should be an official way to do this */
if ((handle.callout->c_func == &ng_timeout_trapoline) &&
(NGI_NODE(item) == node) &&
(callout_stop(handle.callout))) {
/*
* We successfully removed it from the queue before it ran
* So now we need to unreference everything that was
* given extra references. (NG_FREE_ITEM does this).
*/
mtx_unlock_spin(&callout_lock);
NG_FREE_ITEM(item);
return (1);
}
mtx_unlock_spin(&callout_lock);
return (0);
}
/*
* Set the address, if none given, give the node here.
*/