Пример #1
0
static void
flow_send_do(struct sol_flow_node *flow, struct flow_static_data *fsd, uint16_t src_idx, uint16_t source_out_port_idx, struct sol_flow_packet *packet)
{
    struct flow_static_type *type = (struct flow_static_type *)flow->type;
    const struct sol_flow_static_conn_spec *spec;
    unsigned int i;
    bool is_error_packet, dispatched;

    is_error_packet = sol_flow_packet_get_type(packet) == SOL_FLOW_PACKET_TYPE_ERROR;
    dispatched = false;

    for (i = type->node_infos[src_idx].first_conn_idx, spec = type->conn_specs + i; spec->src == src_idx; spec++, i++) {
        const struct sol_flow_port_type_in *dst_port_type;
        struct sol_flow_node *dst;
        struct conn_info *ci;

        if (spec->src_port != source_out_port_idx)
            continue;

        dst = fsd->nodes[spec->dst];
        dst_port_type = sol_flow_node_type_get_port_in(dst->type, spec->dst_port);
        ci = &type->conn_infos[i];

        dispatch_process(dst, spec->dst_port, ci->in_conn_id, dst_port_type, packet);
        dispatched = true;
    }

    if (type->ports_out_count > 0) {
        const struct sol_flow_static_port_spec *pspec;
        uint16_t exported_out;
        for (pspec = type->exported_out_specs, exported_out = 0; pspec->node < UINT16_MAX; pspec++, exported_out++) {
            if (pspec->node == src_idx && pspec->port == source_out_port_idx) {
                /* Export the packet. Note that ownership of packet
                 * will pass to the send() function. */
                sol_flow_send_packet(flow, exported_out, packet);
                return;
            }
        }
    }

    if (is_error_packet && !dispatched) {
        const char *msg;
        int code;

        if (sol_flow_packet_get_error(packet, &code, &msg) == 0) {
            SOL_WRN("Error packet \'%d (%s)\' sent from \'%s (%p)\' was not handled", code,
                msg, flow->id, flow);
        }
    }

    sol_flow_packet_del(packet);
}
Пример #2
0
  ReturnCode
  cell::process()
  {
    configure();
    //trigger all parameter change callbacks...
    tendrils::iterator begin = parameters.begin(), end = parameters.end();

    while (begin != end)
    {
      try
      {
        begin->second->notify();
      } catch (const std::exception& e)
      {
        ECTO_TRACE_EXCEPTION("const std::exception& outside of CATCH ALL");
        BOOST_THROW_EXCEPTION(except::CellException()
                              << except::type(name_of(typeid(e)))
                              << except::what(e.what())
                              << except::cell_name(name())
                              << except::function_name(__FUNCTION__)
                              << except::when("While triggering param change callbacks"))
          ;
      }
      ++begin;
    }
    try
    {
      try
      {
        const ReturnCode rc = dispatch_process(inputs, outputs);
        return rc;
      } catch (const boost::thread_interrupted&) {
        ECTO_TRACE_EXCEPTION("const boost::thread_interrupted&, returning QUIT instead of rethrow");
        return ecto::QUIT;
      }
    } CATCH_ALL()
  }
Пример #3
0
static int
connect_nodes(struct flow_static_type *type, struct flow_static_data *fsd)
{
    const struct sol_flow_static_conn_spec *spec;
    int i, r;

    for (i = 0, spec = type->conn_specs; i < type->conn_count; i++, spec++) {
        const struct sol_flow_port_type_out *src_port_type;
        const struct sol_flow_port_type_in *dst_port_type;
        struct sol_flow_node *src, *dst;
        struct conn_info *ci;
        struct sol_flow_packet *packet = NULL;

        src = fsd->nodes[spec->src];
        dst = fsd->nodes[spec->dst];
        ci = &type->conn_infos[i];

        src_port_type = sol_flow_node_type_get_port_out(src->type, spec->src_port);
        dst_port_type = sol_flow_node_type_get_port_in(dst->type, spec->dst_port);


        SOL_FLOW_PORT_TYPE_OUT_API_CHECK(src_port_type, SOL_FLOW_PORT_TYPE_OUT_API_VERSION, -EINVAL);
        SOL_FLOW_PORT_TYPE_IN_API_CHECK(dst_port_type, SOL_FLOW_PORT_TYPE_IN_API_VERSION, -EINVAL);

        if (!src_port_type->packet_type) {
            CONNECT_NODES_WRN(spec, src->id, dst->id, "Invalid packet type for source port");
            return -EINVAL;
        }
        if (!dst_port_type->packet_type) {
            CONNECT_NODES_WRN(spec, src->id, dst->id, "Invalid packet type for destination port");
            return -EINVAL;
        }

        if (!match_packets(src_port_type->packet_type, dst_port_type->packet_type)) {
            CONNECT_NODES_WRN(spec, src->id, dst->id,
                "Error matching source and destination packet types: %s != %s: %s",
                src_port_type->packet_type->name, dst_port_type->packet_type->name,
                sol_util_strerrora(EINVAL));
            r = -EINVAL;
            goto dispatch_error;
        }

        r = dispatch_connect_out(src, spec->src_port, ci->out_conn_id, src_port_type);
        if (r < 0) {
            CONNECT_NODES_WRN(spec, src->id, dst->id, "Error connecting source: %s", sol_util_strerrora(-r));
            if (packet)
                sol_flow_packet_del(packet);
            goto dispatch_error;
        }

        r = dispatch_connect_in(dst, spec->dst_port, ci->in_conn_id, dst_port_type);
        if (r < 0) {
            CONNECT_NODES_WRN(spec, src->id, dst->id, "Error connecting destination: %s", sol_util_strerrora(-r));
            dispatch_disconnect_out(src, spec->src_port, ci->out_conn_id, src_port_type);
            if (packet)
                sol_flow_packet_del(packet);
            goto dispatch_error;
        }

        inspector_did_connect_port(src, spec->src_port, ci->out_conn_id,
            dst, spec->dst_port, ci->in_conn_id);

        if (!packet)
            continue;

        dispatch_process(dst, spec->dst_port, ci->in_conn_id, dst_port_type, (const struct sol_flow_packet *)packet);
        sol_flow_packet_del(packet);
    }
    SOL_DBG("Making %u connections.", i);

    return 0;

dispatch_error:
    /* Dispatch disconnections in reverse order. Skip current failed
     * iteration since it was handled inside the loop. */
    i--;
    spec--;
    for (; i >= 0; i--, spec--) {
        const struct sol_flow_port_type_out *src_port_type;
        const struct sol_flow_port_type_in *dst_port_type;
        struct sol_flow_node *src, *dst;
        struct conn_info *ci;

        src = fsd->nodes[spec->src];
        dst = fsd->nodes[spec->dst];
        ci = &type->conn_infos[i];

        dst_port_type = sol_flow_node_type_get_port_in(dst->type, spec->dst_port);
        dispatch_disconnect_in(dst, spec->dst_port, ci->in_conn_id, dst_port_type);

        src_port_type = sol_flow_node_type_get_port_out(src->type, spec->src_port);
        dispatch_disconnect_out(src, spec->src_port, ci->out_conn_id, src_port_type);
    }

    return r;
}