summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>2002-03-05 20:26:20 +0000
committerjulian <julian@FreeBSD.org>2002-03-05 20:26:20 +0000
commit7666c3b981c92e074d2721bee3753f0451cedad3 (patch)
tree109002d3d6d09b00beb826858969d2868aeba646
parent8d5b7b21f31ca8890b15763fcb98bc38d3f0cc26 (diff)
downloadFreeBSD-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.h4
-rw-r--r--sys/netgraph/ng_base.c62
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.
*/
OpenPOWER on IntegriCloud