* Make a peer and connect. * We assume that the local node is locked. * The new node probably doesn't need a lock until * it has a hook, because it cannot really have any work until then, * but we should think about it a bit more. * * The problem may come if the other node also fires up * some hardware or a timer or some other source of activation, * also it may already get a command msg v
| 1544 | * an unconnected node? |
| 1545 | */ |
| 1546 | static int |
| 1547 | ng_mkpeer(node_p node, const char *name, const char *name2, char *type) |
| 1548 | { |
| 1549 | node_p node2; |
| 1550 | hook_p hook1, hook2; |
| 1551 | int error; |
| 1552 | |
| 1553 | if ((error = ng_make_node(type, &node2))) { |
| 1554 | return (error); |
| 1555 | } |
| 1556 | |
| 1557 | if ((error = ng_add_hook(node, name, &hook1))) { /* gives us a ref */ |
| 1558 | ng_rmnode(node2, NULL, NULL, 0); |
| 1559 | return (error); |
| 1560 | } |
| 1561 | |
| 1562 | if ((error = ng_add_hook(node2, name2, &hook2))) { |
| 1563 | ng_rmnode(node2, NULL, NULL, 0); |
| 1564 | ng_destroy_hook(hook1); |
| 1565 | NG_HOOK_UNREF(hook1); |
| 1566 | return (error); |
| 1567 | } |
| 1568 | |
| 1569 | /* |
| 1570 | * Actually link the two hooks together. |
| 1571 | */ |
| 1572 | hook1->hk_peer = hook2; |
| 1573 | hook2->hk_peer = hook1; |
| 1574 | |
| 1575 | /* Each hook is referenced by the other */ |
| 1576 | NG_HOOK_REF(hook1); |
| 1577 | NG_HOOK_REF(hook2); |
| 1578 | |
| 1579 | /* Give each node the opportunity to veto the pending connection */ |
| 1580 | if (hook1->hk_node->nd_type->connect) { |
| 1581 | error = (*hook1->hk_node->nd_type->connect) (hook1); |
| 1582 | } |
| 1583 | |
| 1584 | if ((error == 0) && hook2->hk_node->nd_type->connect) { |
| 1585 | error = (*hook2->hk_node->nd_type->connect) (hook2); |
| 1586 | } |
| 1587 | |
| 1588 | /* |
| 1589 | * drop the references we were holding on the two hooks. |
| 1590 | */ |
| 1591 | if (error) { |
| 1592 | ng_destroy_hook(hook2); /* also zaps hook1 */ |
| 1593 | ng_rmnode(node2, NULL, NULL, 0); |
| 1594 | } else { |
| 1595 | /* As a last act, allow the hooks to be used */ |
| 1596 | hook1->hk_flags &= ~HK_INVALID; |
| 1597 | hook2->hk_flags &= ~HK_INVALID; |
| 1598 | } |
| 1599 | NG_HOOK_UNREF(hook1); |
| 1600 | NG_HOOK_UNREF(hook2); |
| 1601 | return (error); |
| 1602 | } |
| 1603 |
no test coverage detected