Пример #1
0
static void
flow_node_close(struct sol_flow_node *node, void *data)
{
    struct flow_static_type *type = (struct flow_static_type *)node->type;
    struct flow_static_data *fsd = data;
    int i;

    if (fsd->delay_send)
        sol_timeout_del(fsd->delay_send);
    while (!sol_list_is_empty(&fsd->delayed_packets)) {
        struct delayed_packet *dp;
        struct sol_list *itr = fsd->delayed_packets.next;
        dp = SOL_LIST_GET_CONTAINER(itr, struct delayed_packet, list);
        sol_list_remove(itr);
        sol_flow_packet_del(dp->packet);
        free(dp);
    }

    teardown_connections(type, fsd);

    for (i = type->node_count - 1; i >= 0; i--)
        sol_flow_node_fini(fsd->nodes[i]);

    free(fsd->node_storage);
    free(fsd->nodes);

    if (type->owned_by_node)
        sol_flow_static_del_type(&type->base.base);
}
Пример #2
0
SOL_API void
sol_flow_node_del(struct sol_flow_node *node)
{
    SOL_FLOW_NODE_CHECK(node);
    sol_flow_node_fini(node);
    free(node);
}
Пример #3
0
static int
flow_node_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options)
{
    struct flow_static_type *type;
    struct flow_static_data *fsd;
    const struct sol_flow_static_node_spec *spec;
    char *node_storage_it;
    int r, i;

    type = (struct flow_static_type *)node->type;
    fsd = data;

    fsd->nodes = calloc(type->node_count, sizeof(struct sol_flow_node *));
    fsd->node_storage = calloc(1, type->node_storage_size);
    if (!fsd->nodes || !fsd->node_storage) {
        r = -ENOMEM;
        goto error_alloc;
    }

    /* Assure flow_send_idle()'s timeout is the first registered, so
     * that timeouts coming from nodes' init/open functions and that
     * may produce packets will always have them delivered */
    r = flow_delay_send(node, fsd);
    SOL_INT_CHECK(r, < 0, r);

    sol_list_init(&fsd->delayed_packets);

    /* Set all pointers before calling nodes methods */
    node_storage_it = fsd->node_storage;
    for (spec = type->node_specs, i = 0; spec->type != NULL; spec++, i++) {
        struct sol_flow_node *child_node = (struct sol_flow_node *)node_storage_it;

        fsd->nodes[i] = child_node;
        child_node->parent_data = INT_TO_PTR(i);
        node_storage_it += calc_node_size(spec);
    }

    for (spec = type->node_specs, i = 0; spec->type != NULL; spec++, i++) {
        struct sol_flow_node *child_node = fsd->nodes[i];
        struct sol_flow_node_options *child_opts;

        child_opts = sol_flow_node_get_options(spec->type, spec->opts);
        if (!child_opts) {
            SOL_WRN("failed to get options for node #%u, type=%p: %s",
                (unsigned)(spec - type->node_specs), spec->type,
                sol_util_strerrora(errno));
        }

        if (type->child_opts_set)
            type->child_opts_set(i, options, child_opts);
        r = sol_flow_node_init(child_node, node, spec->name, spec->type,
            child_opts);
        sol_flow_node_free_options(spec->type, child_opts);
        if (r < 0) {
            SOL_WRN("failed to init node #%u, type=%p, opts=%p: %s",
                (unsigned)(spec - type->node_specs), spec->type, spec->opts,
                sol_util_strerrora(-r));
            goto error_nodes;
        }
    }

    r = connect_nodes(type, fsd);
    if (r < 0)
        goto error_conns;

    return 0;

error_conns:
error_nodes:
    /* Skip the failed index, since it doesn't need fini. */
    for (i--; i >= 0; i--)
        sol_flow_node_fini(fsd->nodes[i]);

error_alloc:
    free(fsd->node_storage);
    free(fsd->nodes);

    return r;
}