diff options
author | julian <julian@FreeBSD.org> | 2002-03-05 20:26:20 +0000 |
---|---|---|
committer | julian <julian@FreeBSD.org> | 2002-03-05 20:26:20 +0000 |
commit | 7666c3b981c92e074d2721bee3753f0451cedad3 (patch) | |
tree | 109002d3d6d09b00beb826858969d2868aeba646 | |
parent | 8d5b7b21f31ca8890b15763fcb98bc38d3f0cc26 (diff) | |
download | FreeBSD-src-7666c3b981c92e074d2721bee3753f0451cedad3.zip FreeBSD-src-7666c3b981c92e074d2721bee3753f0451cedad3.tar.gz |
Official timeout routines for netgraph nodes that know how to
use (and abuse) the node locking system.
MFC after: 1 week
-rw-r--r-- | sys/netgraph/netgraph.h | 4 | ||||
-rw-r--r-- | sys/netgraph/ng_base.c | 62 |
2 files changed, 66 insertions, 0 deletions
diff --git a/sys/netgraph/netgraph.h b/sys/netgraph/netgraph.h index 33fcfb0..97ba84d 100644 --- a/sys/netgraph/netgraph.h +++ b/sys/netgraph/netgraph.h @@ -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 diff --git a/sys/netgraph/ng_base.c b/sys/netgraph/ng_base.c index 00b316b..6acea35 100644 --- a/sys/netgraph/ng_base.c +++ b/sys/netgraph/ng_base.c @@ -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. */ |