FTW_PRIVATE_SUPPORT void ftw_libuv_callback_read_pipe (uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
{
    struct ftw_libuv_stream *context;
    LStrHandle message;
    MgErr lv_err;

    /*  Preconditions expected of FTW. */
    ftw_assert(stream->data);

    message = ftw_recover_LStrHandle (buf->base);

    /*  This is analogous to EAGAIN; silently dispose unused buffer. */
    if (nread <= 0) {
        if (nread == UV_EOF) {
            uv_close ((uv_handle_t *) stream, NULL);
        }

        if (message) {
            lv_err = DSDisposeHandle (message);
            ftw_assert (lv_err == mgNoErr);
        }
        return;
    }

    context = stream->data;

    LHStrPtr (message)->cnt = (int32) nread;

    lv_err = PostLVUserEvent(*(context->msg_to_lv_event), &message);

    lv_err = DSDisposeHandle (message);

    ftw_assert (lv_err == mgNoErr);
}
void LVException::postLVErrorEvent(LVUserEventRef * errorUserEvent) {
	lvError errorCluster;
	populateErrorCluster(&errorCluster);

	// Post to the Event structure
	PostLVUserEvent(*errorUserEvent, &errorCluster);

	// Dispose of the string handle.
	if (errorCluster.source)
		DSDisposeHandle(errorCluster.source);
}
Exemplo n.º 3
0
static void ftw_subscriber_async_recv_thread(void *arg)
{
    LStrHandle msg_sent_to_lv;
    struct ftw_socket *self;
    void *recv_buf;
    MgErr lv_err;
    int socket_err;
    int rc;

    ftw_assert(arg);

    /*  Create local pointer to arguments and notify launching process this thread is constructed. */
    self = ((struct ftw_socket *) arg);
    nn_sem_post(&self->async_recv_ready);

    lv_err = mgNoErr;
    socket_err = 0;

    /*  This broker relays messages from the nanomsg socket into the LabVIEW incoming message queue. */
    while (!lv_err && !socket_err) {

        rc = nn_recv(self->id, &recv_buf, NN_MSG, 0);

        if (rc < 0) {
            socket_err = ((errno == ETIMEDOUT || errno == EAGAIN) ? 0 : errno);
            continue;
        }

        msg_sent_to_lv = (LStrHandle)DSNewHandle(rc);
        lv_err = ftw_support_buffer_to_LStrHandle(&msg_sent_to_lv, recv_buf, rc);
        if (lv_err)
            continue;

        /*  On the LabVIEW side, the handler is a an event registration, meaning
            LabVIEW will not effectively apply backpressure to the Publisher socket.
            For this reason, care must be taken that the Subscriber keep up with
            the Publisher, yet this consideration has long-existed for the LabVIEW
            developer (since, LV-native primitives will likewise cause a memory leak,
            when Event Registrations are allowed to grow without bound). */
        lv_err = PostLVUserEvent(self->incoming_msg_notifier_event, &msg_sent_to_lv);
        if (lv_err)
            continue;

        lv_err = DSDisposeHandle (msg_sent_to_lv);
        rc = nn_freemsg(recv_buf);
        if (rc) {
            socket_err = errno;
            continue;
        }
    }

    return;
}