示例#1
0
static int
setup_watches(struct subprocess_data *mdata)
{
    mdata->watches.in = sol_fd_add(mdata->pipes.in[0], SOL_FD_FLAGS_IN | SOL_FD_FLAGS_ERR, on_in_read, mdata);
    SOL_NULL_CHECK(mdata->watches.in, -1);

    mdata->watches.err = sol_fd_add(mdata->pipes.err[0], SOL_FD_FLAGS_IN | SOL_FD_FLAGS_ERR, on_err_read, mdata);
    if (!mdata->watches.err) {
        sol_fd_del(mdata->watches.in);
        return -1;
    }

    return 0;
}
示例#2
0
int
process_subprocess_in_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id,
    const struct sol_flow_packet *packet)
{
    struct subprocess_data *mdata = data;
    struct sol_blob *blob;
    struct write_data *w;
    int ret;

    SOL_NULL_CHECK(mdata->fork_run, -EINVAL);
    ret = sol_flow_packet_get_blob(packet, &blob);
    SOL_INT_CHECK(ret, < 0, ret);

    w = sol_vector_append(&mdata->write_data);
    SOL_NULL_CHECK(w, -ENOMEM);

    w->offset = 0;
    w->blob = sol_blob_ref(blob);
    if (mdata->write_data.len > 1)
        return 0;

    mdata->watches.out = sol_fd_add(mdata->pipes.out[1], SOL_FD_FLAGS_OUT | SOL_FD_FLAGS_ERR, on_write, mdata);
    if (!mdata->watches.out) {
        sol_blob_unref(w->blob);
        sol_vector_del_last(&mdata->write_data);
        return -1;
    }

    return 0;
}
示例#3
0
static struct sol_mainloop_source *
event_create_source(sd_event *event)
{
    struct sol_mainloop_source *source;
    struct source_ctx *ctx;

    ctx = malloc(sizeof(*ctx));
    SOL_NULL_CHECK(ctx, NULL);

    ctx->event = sd_event_ref(event);

    ctx->fd_handler = sol_fd_add(sd_event_get_fd(event),
        SOL_FD_FLAGS_IN | SOL_FD_FLAGS_HUP | SOL_FD_FLAGS_ERR,
        on_sd_event_fd, ctx);
    SOL_NULL_CHECK_GOTO(ctx->fd_handler, error_fd);

    source = sol_mainloop_source_add(&source_type, ctx);
    SOL_NULL_CHECK_GOTO(source, error_source);

    return source;

error_source:
    sol_fd_del(ctx->fd_handler);
error_fd:
    sd_event_unref(ctx->event);
    free(ctx);
    return NULL;
}
示例#4
0
文件: udev.c 项目: Achint08/soletta
static int
udev_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options)
{
    struct udev_data *mdata = data;
    struct udev_device *device;
    bool value;
    const struct sol_flow_node_type_udev_boolean_options *opts =
        (const struct sol_flow_node_type_udev_boolean_options *)options;

    SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options,
        SOL_FLOW_NODE_TYPE_UDEV_BOOLEAN_OPTIONS_API_VERSION, -EINVAL);

    mdata->udev = udev_new();
    SOL_NULL_CHECK(mdata->udev, -EINVAL);

    mdata->monitor = udev_monitor_new_from_netlink(mdata->udev, "udev");
    if (!mdata->monitor) {
        SOL_WRN("Fail on create the udev monitor");
        goto monitor_error;
    }

    if (udev_monitor_enable_receiving(mdata->monitor) < 0) {
        SOL_WRN("error: unable to subscribe to udev events");
        goto receive_error;
    }

    mdata->addr = strdup(opts->address);

    mdata->node = node;
    mdata->watch = sol_fd_add(udev_monitor_get_fd(mdata->monitor),
        SOL_FD_FLAGS_IN | SOL_FD_FLAGS_ERR | SOL_FD_FLAGS_HUP,
        _on_event, mdata);

    device = udev_device_new_from_syspath(mdata->udev, mdata->addr);
    if (device) {
        value = true;
        udev_device_unref(device);
    } else {
        value = false;
    }

    return sol_flow_send_boolean_packet(node,
        SOL_FLOW_NODE_TYPE_UDEV_BOOLEAN__OUT__OUT, value);

receive_error:
    mdata->monitor = udev_monitor_unref(mdata->monitor);
monitor_error:
    mdata->udev = udev_unref(mdata->udev);
    return -EINVAL;
}
示例#5
0
SOL_API struct sol_mavlink *
sol_mavlink_connect(const char *addr, const struct sol_mavlink_config *config, const void *data)
{
    struct sol_mavlink *mavlink;
    struct sol_str_slice address;
    int port;

    int (*init) (struct sol_mavlink *mavlink);

    SOL_NULL_CHECK(addr, NULL);

    init = sol_mavlink_parse_addr_protocol(addr, &address, &port);
    SOL_NULL_CHECK(init, NULL);

    mavlink = calloc(1, sizeof(*mavlink));
    SOL_NULL_CHECK(mavlink, NULL);

    mavlink->address = &address;
    SOL_NULL_CHECK_GOTO(mavlink->address, err);

    mavlink->port = port;
    SOL_NULL_CHECK_GOTO(mavlink->port, err);

    mavlink->config = config;
    mavlink->data = data;

    memset(&mavlink->curr_position, 0, sizeof(mavlink->curr_position));
    memset(&mavlink->home_position, 0, sizeof(mavlink->home_position));

    if (init(mavlink) < 0) {
        SOL_ERR("Could not initialize mavlink connection.");
        goto err;
    }

    mavlink->watch = sol_fd_add(mavlink->fd, SOL_FD_FLAGS_IN,
        sol_mavlink_fd_handler, mavlink);
    SOL_NULL_CHECK_GOTO(mavlink->watch, err);

    if (!setup_data_stream(mavlink)) {
        SOL_ERR("Could not setup data stream");
        goto err;
    }

    return mavlink;

err:
    sol_mavlink_free(mavlink);
    return NULL;
}
示例#6
0
int
hijack_main_loop()
{
    int returnValue;
    uv_loop_t *uv_loop = NULL;

    SOL_DBG("Entering with state %s", RESOLVE_MAINLOOP_STATE(mainloopState));
    if (mainloopState == MAINLOOP_HIJACKED ||
        mainloopState == MAINLOOP_HIJACKING_STARTED) {
        return 0;
    }

    uv_loop = uv_default_loop();

    // The actual hijacking starts here, inspired by node-gtk. The plan:
    // 1. uv has two ways of letting us know that it needs to run its loop. One
    //    is that its backend timeout is >= 0, and the other is a file
    //    descriptor which can become readable/writable/errored. So, attach a
    //    source to the soletta main loop which will run the uv main loop in
    //    a non-blocking fashion. Also attach a file descriptor watch via which
    //    uv can signal that it needs to run an iteration.
    // 2. Attach an idler to the uv main loop and call sol_run() from it when
    //    it first runs. This interrupts the uv main loop, because sol_run()
    //    doesn't return but, since we've already added the above sources to
    //    the soletta main loop in the first step, the source or the file
    //    descriptor watch will end up running one non-blocking iteration of
    //    the uv main loop which, in turn, will recursively call the idler we
    //    added. At that point, the idler can remove itself from the uv main
    //    loop. After that, only the soletta main loop runs, but it runs an
    //    iteration of the uv main loop in a non-blocking fashion whenever the
    //    uv main loop signals to the soletta main loop via the attached
    //    source or the attached file descriptor watch.
    // 3. Attach a token handle to the uv main loop which represents all
    //    soletta open handles. This is necessary because the uv main loop
    //    would otherwise quit when it runs out of its own handles. We remove
    //    this token handle when we release the uv main loop so that if, at
    //    that point, it has no more handles, it is free to cause the node.js
    //    process to quit.

    // We allocate the various needed structures only once. After that, we
    // reuse them. We never free them, even if we release the uv main loop.
    if (!uv_loop_source) {
        uv_loop_source = sol_mainloop_add_source(&uv_loop_source_funcs,
            uv_loop);
        if (!uv_loop_source) {
            return -ENOMEM;
        }
    }

    if (!uv_loop_fd) {
        uv_loop_fd = sol_fd_add(uv_backend_fd(uv_loop),
            SOL_FD_FLAGS_IN | SOL_FD_FLAGS_OUT | SOL_FD_FLAGS_ERR,
            uv_loop_fd_changed, uv_loop);
        if (!uv_loop_fd) {
            return -ENOMEM;
        }
    }

    returnValue = uv_prepare_init(uv_loop, &uv_token_handle);
    if (returnValue) {
        return returnValue;
    }

    returnValue = uv_idle_init(uv_loop, &uv_idle);
    if (returnValue) {
        return returnValue;
    }

    SOL_DBG("Starting token handle");
    returnValue = uv_prepare_start(&uv_token_handle, uv_token_callback);
    if (returnValue) {
        return returnValue;
    }

    SOL_DBG("Starting idler");
    returnValue = uv_idle_start(&uv_idle, uv_idle_callback);
    if (returnValue) {
        return returnValue;
    }

    mainloopState = MAINLOOP_HIJACKING_STARTED;
    return 0;
}
示例#7
0
SOL_API struct sol_mavlink *
sol_mavlink_connect(const char *addr, const struct sol_mavlink_config *config, const void *data)
{
    struct sol_mavlink *mavlink;
    struct sol_str_slice address;
    int port;

    int (*init) (struct sol_mavlink *mavlink);

    SOL_NULL_CHECK(addr, NULL);
    SOL_NULL_CHECK(config, NULL);

#ifndef SOL_NO_API_VERSION
    if (SOL_UNLIKELY(config->api_version !=
        SOL_MAVLINK_CONFIG_API_VERSION)) {
        SOL_ERR("Unexpected API version (config is %" PRIu16 ", expected %" PRIu16 ")",
            config->api_version, SOL_MAVLINK_CONFIG_API_VERSION);
        return NULL;
    }

    SOL_NULL_CHECK(config->handlers, NULL);

    if (SOL_UNLIKELY(config->handlers->api_version !=
        SOL_MAVLINK_HANDLERS_API_VERSION)) {
        SOL_ERR("Unexpected API version (config is %" PRIu16 ", expected %" PRIu16 ")",
            config->handlers->api_version, SOL_MAVLINK_HANDLERS_API_VERSION);
        return NULL;
    }
#else
    SOL_NULL_CHECK(config->handlers, NULL);
#endif

    init = sol_mavlink_parse_addr_protocol(addr, &address, &port);
    SOL_NULL_CHECK(init, NULL);

    mavlink = calloc(1, sizeof(*mavlink));
    SOL_NULL_CHECK(mavlink, NULL);

    mavlink->address = &address;
    SOL_NULL_CHECK_GOTO(mavlink->address, err);

    mavlink->port = port;
    SOL_NULL_CHECK_GOTO(mavlink->port, err);

    mavlink->config = config;
    mavlink->data = data;

    memset(&mavlink->curr_position, 0, sizeof(mavlink->curr_position));
    memset(&mavlink->home_position, 0, sizeof(mavlink->home_position));

    if (init(mavlink) < 0) {
        SOL_ERR("Could not initialize mavlink connection.");
        goto err;
    }

    mavlink->watch = sol_fd_add(mavlink->fd, SOL_FD_FLAGS_IN,
        sol_mavlink_fd_handler, mavlink);
    SOL_NULL_CHECK_GOTO(mavlink->watch, err);

    if (!setup_data_stream(mavlink)) {
        SOL_ERR("Could not setup data stream");
        goto err;
    }

    return mavlink;

err:
    sol_mavlink_free(mavlink);
    return NULL;
}