| 2220 | */ |
| 2221 | |
| 2222 | int |
| 2223 | ng_snd_item(item_p item, int flags) |
| 2224 | { |
| 2225 | hook_p hook; |
| 2226 | node_p node; |
| 2227 | int queue, rw; |
| 2228 | struct ng_queue *ngq; |
| 2229 | int error = 0; |
| 2230 | |
| 2231 | /* We are sending item, so it must be present! */ |
| 2232 | KASSERT(item != NULL, ("ng_snd_item: item is NULL")); |
| 2233 | |
| 2234 | #ifdef NETGRAPH_DEBUG |
| 2235 | _ngi_check(item, __FILE__, __LINE__); |
| 2236 | #endif |
| 2237 | |
| 2238 | /* Item was sent once more, postpone apply() call. */ |
| 2239 | if (item->apply) |
| 2240 | refcount_acquire(&item->apply->refs); |
| 2241 | |
| 2242 | node = NGI_NODE(item); |
| 2243 | /* Node is never optional. */ |
| 2244 | KASSERT(node != NULL, ("ng_snd_item: node is NULL")); |
| 2245 | |
| 2246 | hook = NGI_HOOK(item); |
| 2247 | /* Valid hook and mbuf are mandatory for data. */ |
| 2248 | if ((item->el_flags & NGQF_TYPE) == NGQF_DATA) { |
| 2249 | KASSERT(hook != NULL, ("ng_snd_item: hook for data is NULL")); |
| 2250 | if (NGI_M(item) == NULL) |
| 2251 | ERROUT(EINVAL); |
| 2252 | CHECK_DATA_MBUF(NGI_M(item)); |
| 2253 | } |
| 2254 | |
| 2255 | /* |
| 2256 | * If the item or the node specifies single threading, force |
| 2257 | * writer semantics. Similarly, the node may say one hook always |
| 2258 | * produces writers. These are overrides. |
| 2259 | */ |
| 2260 | if (((item->el_flags & NGQF_RW) == NGQF_WRITER) || |
| 2261 | (node->nd_flags & NGF_FORCE_WRITER) || |
| 2262 | (hook && (hook->hk_flags & HK_FORCE_WRITER))) { |
| 2263 | rw = NGQRW_W; |
| 2264 | } else { |
| 2265 | rw = NGQRW_R; |
| 2266 | } |
| 2267 | |
| 2268 | /* |
| 2269 | * If sender or receiver requests queued delivery, or call graph |
| 2270 | * loops back from outbound to inbound path, or stack usage |
| 2271 | * level is dangerous - enqueue message. |
| 2272 | */ |
| 2273 | if ((flags & NG_QUEUE) || (hook && (hook->hk_flags & HK_QUEUE))) { |
| 2274 | queue = 1; |
| 2275 | } else if (hook && (hook->hk_flags & HK_TO_INBOUND) && |
| 2276 | curthread->td_ng_outbound) { |
| 2277 | queue = 1; |
| 2278 | } else { |
| 2279 | queue = 0; |
no test coverage detected