Esempio n. 1
0
static void
C_schedule(lcbio_CTX *ctx)
{
    lcbio_TABLE *io = ctx->io;
    lcb_sockdata_t *sd = CTX_SD(ctx);
    int rv;

    if (ctx->output && ctx->output->rb.nbytes) {
        /** Schedule a write */
        lcb_IOV iov[2];
        unsigned niov;

        ringbuffer_get_iov(&ctx->output->rb, RINGBUFFER_READ, iov);
        niov = iov[1].iov_len ? 2 : 1;
        rv = IOT_V1(io).write2(IOT_ARG(io), sd, iov, niov, ctx->output, Cw_handler);
        if (rv) {
            lcbio_ctx_senderr(ctx, convert_lcberr(ctx, LCBIO_IOERR));
            return;
        } else {
            ctx->output = NULL;
            ctx->npending++;
        }
    }

    if (ctx->wwant) {
        ctx->wwant = 0;
        ctx->procs.cb_flush_ready(ctx);
    }

    if (ctx->rdwant && sd->is_reading == 0) {
        lcb_IOV iov[RWINL_IOVSIZE];
        unsigned ii;
        unsigned niov = rdb_rdstart(&ctx->ior, (nb_IOV *)iov, RWINL_IOVSIZE);

        assert(niov);
        for (ii = 0; ii < niov; ++ii) {
            assert(iov[ii].iov_len);
        }

        rv = IOT_V1(io).read2(IOT_ARG(io), sd, iov, niov, ctx, Cr_handler);
        if (rv) {
            lcbio_ctx_senderr(ctx, convert_lcberr(ctx, LCBIO_IOERR));

        } else {
            sd->is_reading = 1;
            ctx->npending++;
        }
    }
}
Esempio n. 2
0
static void
destroy_cursock(lcbio_CONNSTART *cs)
{
    lcbio_SOCKET *s = cs->sock;
    lcbio_TABLE *iot = s->io;
    if (cs->ai) {
        cs->ai = cs->ai->ai_next;
    }

    if (!cs->ai) {
        return;
    }

    if (IOT_IS_EVENT(iot)) {
        if (cs->ev_active) {
            lcb_assert(s->u.fd != INVALID_SOCKET);
            IOT_V0EV(iot).cancel(IOT_ARG(iot), s->u.fd, cs->event);
            cs->ev_active = 0;
        }
        IOT_V0IO(iot).close(IOT_ARG(iot), s->u.fd);
        s->u.fd = INVALID_SOCKET;
    } else {
        if (s->u.sd) {
            IOT_V1(iot).close(IOT_ARG(iot), s->u.sd);
            s->u.sd = NULL;
        }
    }
}
Esempio n. 3
0
int
lcbio_is_netclosed(lcbio_SOCKET *sock, int flags)
{
    lcbio_pTABLE iot = sock->io;

    if (IOT_IS_EVENT(iot)) {
        return IOT_V0IO(iot).is_closed(IOT_ARG(iot), sock->u.fd, flags);
    } else {
        return IOT_V1(iot).is_closed(IOT_ARG(iot), sock->u.sd, flags);
    }
}
Esempio n. 4
0
static void
C_connect(lcbio_CONNSTART *cs)
{
    int rv;
    lcbio_SOCKET *s = cs->sock;
    int retry_once = 0;
    lcbio_CSERR status;
    lcbio_TABLE *io = s->io;

    GT_NEXTSOCK:
    if (ensure_sock(cs) != 0) {
        lcbio_mksyserr(IOT_ERRNO(io), &cs->syserr);
        cs_state_signal(cs, CS_ERROR, LCB_CONNECT_ERROR);
        return;
    }

    GT_CONNECT:
    rv = IOT_V1(io).connect(IOT_ARG(io), s->u.sd, cs->ai->ai_addr,
                            (unsigned)cs->ai->ai_addrlen, C_conncb);
    if (rv == 0) {
        lcbio_ref(s);
        return;
    }

    lcbio_mksyserr(IOT_ERRNO(io), &cs->syserr);
    status = lcbio_mkcserr(IOT_ERRNO(io));
    switch (status) {

    case LCBIO_CSERR_INTR:
        goto GT_CONNECT;

    case LCBIO_CSERR_CONNECTED:
        cs_state_signal(cs, CS_CONNECTED, LCB_SUCCESS);
        return;

    case LCBIO_CSERR_BUSY:
        return;

    case LCBIO_CSERR_EINVAL:
        if (!retry_once) {
            retry_once = 1;
            goto GT_CONNECT;
        }
        /* fallthrough */

    case LCBIO_CSERR_EFAIL:
    default:
        destroy_cursock(cs);
        goto GT_NEXTSOCK;
    }
}
Esempio n. 5
0
lcb_sockdata_t *
lcbio_C_ai2sock(lcbio_TABLE *io, struct addrinfo **ai, int *connerr)
{
    lcb_sockdata_t *ret = NULL;
    for (; *ai; *ai = (*ai)->ai_next) {
        ret = IOT_V1(io).socket(
                IOT_ARG(io), (*ai)->ai_family, (*ai)->ai_socktype,
                (*ai)->ai_protocol);
        if (ret) {
            return ret;
        } else {
            *connerr = IOT_ERRNO(io);
        }
    }
    return ret;
}
Esempio n. 6
0
static int
C_put_ex(lcbio_CTX *ctx, lcb_IOV *iov, unsigned niov, unsigned nb)
{
    lcbio_TABLE *iot = ctx->io;
    lcb_sockdata_t *sd = CTX_SD(ctx);
    int status = IOT_V1(iot).write2(IOT_ARG(iot),
        sd, iov, niov, (void *)(uintptr_t)nb, Cw_ex_handler);
    if (status) {
        /** error! */
        lcbio_OSERR saverr = IOT_ERRNO(iot);
        ctx->procs.cb_flush_done(ctx, nb, nb);
        lcbio_ctx_senderr(ctx, lcbio_mklcberr(saverr, ctx->sock->settings));
        return 0;
    } else {
        ctx->npending++;
        return 1;
    }
}
Esempio n. 7
0
void
lcbio_shutdown(lcbio_SOCKET *s)
{
    lcbio_TABLE *io = s->io;

    lcbio__protoctx_delall(s);
    if (IOT_IS_EVENT(io)) {
        if (s->u.fd != INVALID_SOCKET) {
            IOT_V0IO(io).close(IOT_ARG(io), s->u.fd);
            s->u.fd = INVALID_SOCKET;
        }
    } else {
        if (s->u.sd) {
            IOT_V1(io).close(IOT_ARG(io), s->u.sd);
            s->u.sd = NULL;
        }
    }
}
Esempio n. 8
0
void
lcbio__load_socknames(lcbio_SOCKET *sock)
{
    int n_salocal, n_saremote, rv;
    struct lcb_nameinfo_st ni;
    lcbio_CONNINFO *info = sock->info;

    n_salocal = sizeof(info->sa_local);
    n_saremote = sizeof(info->sa_remote);
    ni.local.name = (struct sockaddr *)&info->sa_local;
    ni.local.len = &n_salocal;
    ni.remote.name = (struct sockaddr *)&info->sa_remote;
    ni.remote.len = &n_saremote;

    if (!IOT_IS_EVENT(sock->io)) {
        if (!sock->u.sd) {
            return;
        }

        rv = IOT_V1(sock->io).nameinfo(IOT_ARG(sock->io), sock->u.sd, &ni);

        if (ni.local.len == 0 || ni.remote.len == 0 || rv < 0) {
            return;
        }

    } else {
        socklen_t sl_tmp = sizeof(info->sa_local);
        if (sock->u.fd == INVALID_SOCKET) {
            return;
        }

        rv = getsockname(sock->u.fd, ni.local.name, &sl_tmp);
        n_salocal = sl_tmp;
        if (rv < 0) {
            return;
        }
        rv = getpeername(sock->u.fd, ni.remote.name, &sl_tmp);
        n_saremote = sl_tmp;
        if (rv < 0) {
            return;
        }
    }
    info->naddr = n_salocal;
}