示例#1
0
SOL_API struct sol_flow_node *
sol_flow_node_new(struct sol_flow_node *parent, const char *id, const struct sol_flow_node_type *type, const struct sol_flow_node_options *options)
{
    struct sol_flow_node *node;
    int err;
    bool free_opts = false;

    SOL_NULL_CHECK(type, NULL);
    SOL_FLOW_NODE_TYPE_API_CHECK(type, SOL_FLOW_NODE_TYPE_API_VERSION, NULL);

    node = calloc(1, sizeof(*node) + type->data_size);
    SOL_NULL_CHECK(node, NULL);

    if (!options) {
        options = sol_flow_node_get_options(type, NULL);
        free_opts = true;
    }
    err = sol_flow_node_init(node, parent, id, type, options);
    if (err < 0) {
        free(node);
        node = NULL;
        errno = -err;
    }
    if (free_opts)
        sol_flow_node_free_options(type, (struct sol_flow_node_options *)options);

    return node;
}
示例#2
0
SOL_API struct sol_flow_node *
sol_flow_node_new(struct sol_flow_node *parent, const char *id, const struct sol_flow_node_type *type, const struct sol_flow_node_options *options)
{
    struct sol_flow_node *node;
    int err;

    SOL_NULL_CHECK(type, NULL);
    SOL_FLOW_NODE_TYPE_API_CHECK(type, SOL_FLOW_NODE_TYPE_API_VERSION, NULL);

    node = calloc(1, sizeof(*node) + type->data_size);
    SOL_NULL_CHECK(node, NULL);

    if (!options)
        options = type->default_options;
    if (!options)
        options = &sol_flow_node_options_empty;

    err = sol_flow_node_init(node, parent, id, type, options);
    if (err < 0) {
        free(node);
        node = NULL;
        errno = -err;
    }

    return node;
}
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;
}