Ejemplo n.º 1
0
int ftw_socket_inbox_shutdown(struct ftw_socket_inbox ** const sock)
{
    uint64_t time;
    double elapsed_time;
    int rc;

    /*  Preconditions expected of LabVIEW. */
    ftw_assert(sock);

    if (*sock == NULL) {
        errno = EBADF;
        return -1;
    }

    time = uv_hrtime();
    rc = nn_close((*sock)->id);
    nn_sem_post(&(*sock)->deinitialized);
    nn_thread_term(&(*sock)->async_recv_thread);
    nn_sem_term(&(*sock)->msg_acknowledged);
    nn_sem_term(&(*sock)->initialized);
    nn_sem_term(&(*sock)->deinitialized);
    time = uv_hrtime() - time;
    elapsed_time = time / 1000000000.0;
    ftw_debug("Inbox Shutdown time: %.3fsec", elapsed_time);

    return rc;
}
Ejemplo n.º 2
0
int nn_sock_term (struct nn_sock *self)
{
    int rc;
    int i;

    /*  NOTE: nn_sock_stop must have already been called. */

    /*  Some endpoints may still be alive.  Here we are going to wait
        till they are all closed.  This loop is not interruptible, because
        making it so would leave a partially cleaned up socket, and we don't
        have a way to defer resource deallocation. */
    for (;;) {
        rc = nn_sem_wait (&self->termsem);
        if (nn_slow (rc == -EINTR))
            continue;
        errnum_assert (rc == 0, -rc);
        break;
    }

    /*  Also, wait for all holds on the socket to be released.  */
    for (;;) {
        rc = nn_sem_wait (&self->relesem);
        if (nn_slow (rc == -EINTR))
            continue;
        errnum_assert (rc == 0, -rc);
        break;
    }

    /*  Threads that posted the semaphore(s) can still have the ctx locked
        for a short while. By simply entering the context and exiting it
        immediately we can be sure that any such threads have already
        exited the context. */
    nn_ctx_enter (&self->ctx);
    nn_ctx_leave (&self->ctx);

    /*  At this point, we can be reasonably certain that no other thread
        has any references to the socket. */

    nn_fsm_stopped_noevent (&self->fsm);
    nn_fsm_term (&self->fsm);
    nn_sem_term (&self->termsem);
    nn_list_term (&self->sdeps);
    nn_list_term (&self->eps);
    nn_clock_term (&self->clock);
    nn_ctx_term (&self->ctx);

    /*  Destroy any optsets associated with the socket. */
    for (i = 0; i != NN_MAX_TRANSPORT; ++i)
        if (self->optsets [i])
            self->optsets [i]->vfptr->destroy (self->optsets [i]);

    return 0;
}
Ejemplo n.º 3
0
int ftw_socket_close(struct ftw_socket * const sock)
{
    int rc;

    /*  Preconditions expected of LabVIEW. */
    ftw_assert(sock);

    rc = nn_close(sock->id);
    if (rc != 0) {
        return rc;
    }

    /*  A non-NULL Dynamic Event Reference means this socket has an asynchronous recv thread that must shut down. */
    if (sock->incoming_msg_notifier_event) {
        nn_thread_term(&sock->async_recv_thread);
        nn_sem_term(&sock->async_recv_ready);
        nn_sem_term(&sock->msg_acknowledged);
    }

    return 0;
}
Ejemplo n.º 4
0
int nn_sock_term (struct nn_sock *self)
{
    int rc;
    int i;

    /*  Ask the state machine to start closing the socket. */
    nn_ctx_enter (&self->ctx);
    nn_fsm_stop (&self->fsm);
    nn_ctx_leave (&self->ctx);

    /*  Shutdown process was already started but some endpoints may still
        alive. Here we are going to wait till they are all closed. */
    rc = nn_sem_wait (&self->termsem);
    if (nn_slow (rc == -EINTR))
        return -EINTR;
    errnum_assert (rc == 0, -rc);

    /*  The thread that posted the semaphore can still have the ctx locked
        for a short while. By simply entering the context and exiting it
        immediately we can be sure that the thread in question have already
        exited the context. */
    nn_ctx_enter (&self->ctx);
    nn_ctx_leave (&self->ctx);

    /*  Deallocate the resources. */
    nn_fsm_stopped_noevent (&self->fsm);
    nn_fsm_term (&self->fsm);
    nn_sem_term (&self->termsem);
    nn_list_term (&self->sdeps);
    nn_list_term (&self->eps);
    nn_clock_term (&self->clock);
    nn_ctx_term (&self->ctx);

    /*  Destroy any optsets associated with the socket. */
    for (i = 0; i != NN_MAX_TRANSPORT; ++i)
        if (self->optsets [i])
            self->optsets [i]->vfptr->destroy (self->optsets [i]);

    return 0;
}