static ng_ID_t ng_decodeidname(const char *name);
static int ngb_mod_event(module_t mod, int event, void *data);
static void ngthread(void *dummy);
-static int ng_apply_item(node_p node, item_p item);
+static int ng_apply_item(item_p item);
static node_p ng_ID2noderef(ng_ID_t ID);
static int ng_con_nodes(item_p item, node_p node, const char *name,
node_p node2, const char *name2);
}
/* The item wasn't queued. Deal with it synchronously. */
- NGI_GET_NODE(item, node); /* zaps stored node */
item->depth++;
- error = ng_apply_item(node, item);
-
- /*
- * Node may go away as soon as we remove the reference.
- * Whatever we do, DO NOT access the node again!
- */
- NG_NODE_UNREF(node);
+ error = ng_apply_item(item); /* Removes node reference! */
return (error);
* If there is apply pointer and we own the last reference, call apply().
*/
static int
-ng_apply_item(node_p node, item_p item)
+ng_apply_item(item_p item)
{
hook_p hook;
+ node_p node;
ng_rcvdata_t *rcvdata;
ng_rcvmsg_t *rcvmsg;
- struct ng_apply_info *apply;
- int error = 0, depth, rw;
+ int free_item = 0;
+ int error = 0, rw;
/* Node and item are never optional. */
- KASSERT(node != NULL, ("ng_apply_item: node is NULL"));
KASSERT(item != NULL, ("ng_apply_item: item is NULL"));
-
- NGI_GET_HOOK(item, hook); /* clears stored hook */
+ NGI_GET_NODE(item, node); /* zaps stored node */
+ KASSERT(node != NULL, ("ng_apply_item: node is NULL"));
+ NGI_GET_HOOK(item, hook); /* clears stored hook */
/*
* If the item or the node specifies single threading, force
_ngi_check(item, __FILE__, __LINE__);
#endif
- apply = item->apply;
- depth = item->depth;
-
switch (item->el_flags & NGQF_TYPE) {
case NGQF_DATA:
/*
if (NG_HOOK_NOT_VALID(hook) ||
NG_NODE_NOT_VALID(node)) {
error = EIO;
- NG_FREE_ITEM(item);
+ free_item = 1;
break;
}
/*
if ((!(rcvdata = hook->hk_rcvdata))
&& (!(rcvdata = NG_HOOK_NODE(hook)->nd_type->rcvdata))) {
error = 0;
- NG_FREE_ITEM(item);
+ free_item = 1;
break;
}
error = (*rcvdata)(hook, item);
if (NG_NODE_NOT_VALID(node)) {
TRAP_ERROR();
error = EINVAL;
- NG_FREE_ITEM(item);
+ free_item = 1;
break;
}
/*
(!(rcvmsg = node->nd_type->rcvmsg))) {
TRAP_ERROR();
error = 0;
- NG_FREE_ITEM(item);
+ free_item = 1;
break;
}
error = (*rcvmsg)(node, item, hook);
&& (NGI_FN(item) != &ng_rmnode)) {
TRAP_ERROR();
error = EINVAL;
- NG_FREE_ITEM(item);
+ free_item = 1;
break;
}
if ((item->el_flags & NGQF_TYPE) == NGQF_FN) {
(*NGI_FN(item))(node, hook, NGI_ARG1(item),
NGI_ARG2(item));
- NG_FREE_ITEM(item);
+ free_item = 1;
} else /* it is NGQF_FN2 */
error = (*NGI_FN2(item))(node, item, hook);
break;
ng_leave_write(node);
/* Apply callback. */
- if (apply != NULL) {
- KKASSERT(apply->apply != NULL);
- if (depth == 1 && error != 0)
- apply->error = error;
- if (refcount_release(&apply->refs)) {
- (*apply->apply)(apply->context, apply->error);
+ if (item->apply != NULL) {
+ KKASSERT(item->apply->apply != NULL);
+ if (item->depth == 1 && error != 0)
+ item->apply->error = error;
+ if (refcount_release(&item->apply->refs)) {
+ (*item->apply->apply)(item->apply->context,
+ item->apply->error);
ng_free_apply(item->apply);
item->apply = NULL;
}
}
+ if(free_item)
+ NG_FREE_ITEM(item);
+ NG_NODE_UNREF(node);
+
return (error);
}
while ((msg = lwkt_waitport(&ng_msgport, 0)) != NULL) {
item_p item = (void *)msg;
- node_p node;
- NGI_GET_NODE(item, node); /* zaps stored node */
- ng_apply_item(node, item);
- NG_NODE_UNREF(node);
+ ng_apply_item(item);
}
}