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++; } } }
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; } } }
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); } }
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; } }
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; }
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; } }
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; } } }
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; }