lcbio_CTX * lcbio_ctx_new(lcbio_SOCKET *sock, void *data, const lcbio_EASYPROCS *procs) { lcbio_CTX *ctx = calloc(1, sizeof(*ctx)); ctx->sock = sock; sock->ctx = ctx; ctx->io = sock->io; ctx->data = data; ctx->procs = *procs; ctx->state = ES_ACTIVE; ctx->as_err = lcbio_timer_new(ctx->io, ctx, err_handler); ctx->subsys = "unknown"; rdb_init(&ctx->ior, sock->settings->allocator_factory()); lcbio_ref(sock); if (IOT_IS_EVENT(ctx->io)) { ctx->event = IOT_V0EV(ctx->io).create(IOT_ARG(ctx->io)); ctx->fd = sock->u.fd; } else { ctx->sd = sock->u.sd; } ctx->procs = *procs; ctx->state = ES_ACTIVE; lcb_log(LOGARGS(ctx, DEBUG), CTX_LOGFMT "Pairing with SOCK=%p", CTX_LOGID(ctx), (void*)sock); return ctx; }
static void close_cb(lcbio_SOCKET *s, int reusable, void *arg) { *(lcbio_SOCKET **)arg = s; lcbio_ref(s); lcb_assert(reusable); }
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; } }