summaryrefslogtreecommitdiffstats
path: root/sys/netgraph/ng_base.c
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2005-07-05 17:35:20 +0000
committerglebius <glebius@FreeBSD.org>2005-07-05 17:35:20 +0000
commitfcbdfd0eb4f509af7f2a382daaf2c52ce49704c8 (patch)
tree7c65a2a332dab7cec59b3eb4bdcbf403ceaac133 /sys/netgraph/ng_base.c
parent9c552f7c01059c885fb0604e8fc082ce51f3228a (diff)
downloadFreeBSD-src-fcbdfd0eb4f509af7f2a382daaf2c52ce49704c8.zip
FreeBSD-src-fcbdfd0eb4f509af7f2a382daaf2c52ce49704c8.tar.gz
In the splnet times, netgraph was functional and synchronous. Nowadays,
an item may be queued and processed later. While this is OK for mbufs, this is a problem for control messages. In the framework: - Add optional callback function pointer to an item. When item gets applied the callback is executed from ng_apply_item(). - Add new flag NG_PROGRESS. If this flag is supplied, then return EINPROGRESS instead of 0 in case if item failed to deliver synchronously and was queued. - Honor NG_PROGRESS in ng_snd_item(). In ng_socket: - When userland sends control message add callback to the item. - If ng_snd_item() returns EINPROGRESS, then sleep. This change fixes possible races in ngctl(8) scripts. Reviewed by: julian Approved by: re (scottl)
Diffstat (limited to 'sys/netgraph/ng_base.c')
-rw-r--r--sys/netgraph/ng_base.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/sys/netgraph/ng_base.c b/sys/netgraph/ng_base.c
index 00650eec..5a9f8d9 100644
--- a/sys/netgraph/ng_base.c
+++ b/sys/netgraph/ng_base.c
@@ -2211,7 +2211,11 @@ ng_snd_item(item_p item, int flags)
ng_setisr(node);
}
mtx_unlock_spin(&(ngq->q_mtx));
- return (0);
+
+ if (flags & NG_PROGRESS)
+ return (EINPROGRESS);
+ else
+ return (0);
}
/*
* Take a queue item and a node and see if we can apply the item to
@@ -2237,7 +2241,10 @@ ng_snd_item(item_p item, int flags)
* have been queued in thises cases.
*/
if (item == NULL) {
- return (0);
+ if (flags & NG_PROGRESS)
+ return (EINPROGRESS);
+ else
+ return (0);
}
#ifdef NETGRAPH_DEBUG
@@ -2333,11 +2340,25 @@ ng_apply_item(node_p node, item_p item)
int error = 0;
ng_rcvdata_t *rcvdata;
ng_rcvmsg_t *rcvmsg;
+ ng_apply_t *apply = NULL;
+ void *context = NULL;
NGI_GET_HOOK(item, hook); /* clears stored hook */
#ifdef NETGRAPH_DEBUG
_ngi_check(item, __FILE__, __LINE__);
#endif
+
+ /*
+ * If item has apply callback, store it. Clear callback
+ * immediately, two avoid another call in case if
+ * item would be reused by destination node.
+ */
+ if (item->apply != NULL) {
+ apply = item->apply;
+ context = item->context;
+ item->apply = NULL;
+ }
+
switch (item->el_flags & NGQF_TYPE) {
case NGQF_DATA:
/*
@@ -2453,6 +2474,11 @@ ng_apply_item(node_p node, item_p item)
} else {
ng_leave_write(&node->nd_input_queue);
}
+
+ /* Apply callback. */
+ if (apply != NULL)
+ (*apply)(context, error);
+
return (error);
}
OpenPOWER on IntegriCloud