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);
}
Esempio 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;
}
void LVlinear_print_function(const char * message){
	LVUserEventRef *usrEv = loggingUsrEv;
	if (usrEv != nullptr && message != nullptr){
		// Filter out the progress messages (.....)
		if (strcmp(message, ".") != 0){
			// Move the string to a handle
			size_t length = strlen(message);
			LStrHandle lvmsg = (LStrHandle)DSNewHandle(sizeof(int32_t) + length);
			MoveBlock(message, (*lvmsg)->str, length);
			(*lvmsg)->cnt = static_cast<int32>(length);

			// Post the string to the user event
			PostLVUserEvent(*usrEv, &lvmsg);
		}
	}
}
Esempio n. 5
0
void ftw_socket_inbox_async_recv_worker(void *arg)
{
    /*  Opaque pointer into ftw_incoming_request structure using LabVIEW-safe type for PostLVUserEvent. */
    int64 opaque;
    struct ftw_incoming_request *incoming;
    struct ftw_socket_inbox *self;
    struct nn_iovec iov;
    struct nn_msghdr msg;
    void *msg_ptr;
    void *hdr_ptr;
    MgErr lv_err;
    int socket_err;
    int rc;

    /*  Notify launching process this thread is constructed. */
    ftw_assert(arg);
    self = (struct ftw_socket_inbox *) arg;
    nn_sem_post(&self->initialized);

    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) {

        /* Created here, this incoming request should be freed once the response is sent. */
        incoming = ftw_malloc(sizeof(struct ftw_incoming_request));
        if (incoming == NULL) {
            lv_err = mFullErr;
            continue;
        }
        
        iov.iov_base = &msg_ptr;
        iov.iov_len = NN_MSG;

        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
        msg.msg_control = &hdr_ptr;
        msg.msg_controllen = NN_MSG;

        rc = nn_recvmsg(self->id, &msg, 0);
        if (rc >= 0) {

            incoming->inbox = self;
            incoming->msg_ptr = msg_ptr;
            incoming->msg_len = nn_chunk_size(msg_ptr);
            incoming->hdr_ptr = hdr_ptr;
            incoming->hdr_len = nn_chunk_size(hdr_ptr);

            opaque = (int64)incoming;
            lv_err = PostLVUserEvent(self->incoming_msg_notifier_event, &opaque);
            ftw_assert(lv_err == mgNoErr);

            /*  On the LabVIEW side, the handler is a an Event Handler Structure, which
            applies no backpressure since the event queue cannot be limited for dynamic
            events. For this reason, a semaphore is introduced to simulate blocking backpressure,
            where the semaphore is posted once the Inbox Message Router receives the message. */
            nn_sem_wait(&self->msg_acknowledged);
        }
        else {
            /*  Treat timeouts as non-fatal. Anything else will stop this thread. */
            socket_err = ((errno == ETIMEDOUT || errno == EAGAIN) ? 0 : errno);
        }
    }

    /*  Posting a NULL pointer signals the LabVIEW Message Router to shutdown. */
    opaque = (int64) NULL;
    lv_err = PostLVUserEvent(self->incoming_msg_notifier_event, &opaque);
    ftw_assert(lv_err == mgNoErr);

    /*  Wait for the Message Router to unload. */
    nn_sem_wait(&self->deinitialized);

    return;
}
#ifdef COMPILE_PHIDGETS_LABVIEW

#include "phidget_labview.h"

LV_CFHANDLE_0(, Attach, lvNothing)
LV_CFHANDLE_0(, Detach, lvNothing)
LV_CFHANDLE_0(, ServerConnect, lvNothing)
LV_CFHANDLE_0(, ServerDisconnect, lvNothing)
LV_CFHANDLE_BODY(, Error, lvError, void *userPtr, int val1, const char *val2)
	data->val1 = val1;
    data->val2=(LStrHandle)DSNewHandle(sizeof(int32)+255*sizeof(char));
	memset(LStrBuf(*data->val2),'\0',255);
	snprintf((char*)LStrBuf(*data->val2),255,"%s",val2);
	LStrLen(*data->val2)=strlen(val2);

    ret = PostLVUserEvent(ev, data);

	DSDisposeHandle(data->val2);
    DSDisposePtr(data);
	return EPHIDGET_OK;
}

LV_CFHANDLE_2(Accelerometer, AccelerationChange, lvIndexedDouble, int, double)

LV_CFHANDLE_2(AdvancedServo, PositionChange, lvIndexedDouble, int, double)
LV_CFHANDLE_2(AdvancedServo, VelocityChange, lvIndexedDouble, int, double)
LV_CFHANDLE_2(AdvancedServo, CurrentChange, lvIndexedDouble, int, double)

LV_CFHANDLE_2(Bridge, BridgeData, lvIndexedDouble, int, double)

LV_CFHANDLE_2(Encoder, InputChange, lvIndexedInt32, int, int)