void aio_istream::read_wait(int timeout /* = 0 */) { // 设置流的异步读超时时间 if (timeout >= 0) ACL_AIO_SET_TIMEOUT(stream_, timeout); acl_aio_enable_read(stream_, read_wakeup, this); }
static void body_get(ACL_ASTREAM *astream, HTTP_CHAT_CTX *ctx) { if (ctx->chunked) ctx->status = CHAT_S_CHUNK_HDR; else ctx->status = CHAT_S_CHUNK_DAT; acl_aio_enable_read(astream, body_can_read, ctx); }
static int hdr_can_read(ACL_ASTREAM *astream, void *context) { HTTP_CHAT_CTX *ctx = (HTTP_CHAT_CTX *) context; HTTP_HDR *hdr = ctx->hdr; HTTP_HDR_NOTIFY notify = ctx->notify.hdr_notify; void *arg = ctx->arg; ACL_VSTRING *sbuf; char *data; int dlen; int ret; while (1) { if ((ret = acl_aio_can_read(astream)) == ACL_VSTREAM_EOF) { notify(HTTP_CHAT_ERR_IO, arg); return (-1); } else if (ret == 0) { break; } sbuf = acl_aio_gets_nonl_peek(astream); if (sbuf == NULL) { break; } data = acl_vstring_str(sbuf); dlen = (int) ACL_VSTRING_LEN(sbuf); ACL_VSTRING_RESET(sbuf); ret = hdr_ready(hdr, data, dlen); switch (ret) { case HTTP_CHAT_CONTINUE: break; case HTTP_CHAT_OK: DISABLE_READ(astream); if (notify(ret, arg) < 0) { return (0); } return (0); default: DISABLE_READ(astream); (void) notify(ret, arg); return (0); } } acl_aio_enable_read(astream, hdr_can_read, ctx); return (0); }
static int body_can_read(ACL_ASTREAM *astream, void *context) { const char *myname = "body_can_read"; HTTP_CHAT_CTX *ctx = (HTTP_CHAT_CTX*) context; HTTP_BODY_NOTIFY notify = ctx->notify.body_notify; void *arg = ctx->arg; int ret; while (1) { if ((ret = acl_aio_can_read(astream)) == ACL_VSTREAM_EOF) { (void) notify(HTTP_CHAT_ERR_IO, NULL, 0, arg); return (-1); } else if (ret == 0) { break; } switch (ctx->status) { case CHAT_S_CHUNK_HDR: ret = chunked_hdr(astream, ctx); break; case CHAT_S_CHUNK_DAT: ret = chunked_data(astream, ctx); break; case CHAT_S_CHUNK_SEP: ret = chunked_data_endl(astream, ctx); break; case CHAT_S_CHUNK_TAL: ret = chunked_trailer(astream, ctx); break; default: acl_msg_error("%s(%d): unknown status(%d)", myname, __LINE__, ctx->status); return (-1); } if (ret < 0) { return (-1); } else if (ret == 1) { return (0); } } acl_aio_enable_read(astream, body_can_read, ctx); return (0); }
static void hdr_get_async(ctx_type type, HTTP_HDR *hdr, ACL_ASTREAM *astream, HTTP_HDR_NOTIFY notify, void *arg, int timeout) { const char *myname = "hdr_get_async"; HTTP_CHAT_CTX *ctx; ACL_VSTREAM *stream; if (hdr == NULL || astream == NULL || notify == NULL) acl_msg_fatal("%s: input invalid", myname); stream = acl_aio_vstream(astream); stream->rw_timeout = 0; /* bug fix, --zsx, 2007.7.7 */ if (hdr->chat_ctx == NULL) { hdr->chat_ctx = new_ctx(type); hdr->chat_free_ctx_fn = free_ctx_fn; } ctx = (HTTP_CHAT_CTX*) hdr->chat_ctx; ctx->hdr = hdr; ctx->timeout = timeout; ctx->notify.hdr_notify = notify; ctx->arg = arg; ctx->status = CHAT_S_HDR; if (0) { acl_aio_ctl(astream, ACL_AIO_CTL_READ_HOOK_ADD, hdr_gets_ready, ctx, ACL_AIO_CTL_TIMEOUT, timeout, ACL_AIO_CTL_END); acl_aio_gets_nonl(astream); } else { acl_aio_ctl(astream, ACL_AIO_CTL_TIMEOUT, timeout, ACL_AIO_CTL_END); acl_aio_enable_read(astream, hdr_can_read, ctx); } }