[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC Patch v4 8/8] introduce a new API to aync read data from fd
In colo mode, we will read some data from an fd. Introduce a new API to avoid redundant codes. Signed-off-by: Wen Congyang <wency@xxxxxxxxxxxxxx> --- tools/libxl/libxl_aoutils.c | 73 ++++++++++++++++++++++++++++++++++++++++++++ tools/libxl/libxl_internal.h | 30 ++++++++++++++++++ 2 files changed, 103 insertions(+) diff --git a/tools/libxl/libxl_aoutils.c b/tools/libxl/libxl_aoutils.c index 3e0c0ae..2d36403 100644 --- a/tools/libxl/libxl_aoutils.c +++ b/tools/libxl/libxl_aoutils.c @@ -542,3 +542,76 @@ bool libxl__async_exec_inuse(const libxl__async_exec_state *aes) assert(time_inuse == child_inuse); return child_inuse; } + + +/*----- data reader -----*/ + +static void libxl__datareader_init(libxl__datareader_state *drs) +{ + assert(drs->ao); + libxl__ev_fd_init(&drs->toread); + drs->used = 0; +} + +static void libxl__datareader_kill(libxl__datareader_state *drs) +{ + STATE_AO_GC(drs->ao); + + libxl__ev_fd_deregister(gc, &drs->toread); +} + +static void datareader_callback(libxl__egc *egc, libxl__datareader_state *drs, + ssize_t size, int errnoval) +{ + libxl__datareader_kill(drs); + drs->callback(egc, drs, size, errnoval); +} + +static void datareader_readable(libxl__egc *egc, libxl__ev_fd *ev, + int fd, short events, short revents) +{ + libxl__datareader_state *drs = CONTAINER_OF(ev, *drs, toread); + STATE_AO_GC(drs->ao); + int r; + + if (revents & ~POLLIN) { + LOG(ERROR, "unexpected poll event 0x%x (should be POLLIN) on %s", + revents, drs->readwhat); + datareader_callback(egc, drs, -1, 0); + return; + } + + assert(revents & POLLIN); + while (1) { + r = read(ev->fd, drs->buf + drs->used, drs->readsize - drs->used); + if (r < 0) { + if (errno == EINTR) + continue; + if (errno == EWOULDBLOCK) + break; + LOGE(ERROR, "error reading %s", + drs->readwhat); + datareader_callback(egc, drs, 0, errno); + return; + } + if (r == 0) { + datareader_callback(egc, drs, drs->used, 0); + break; + } + + drs->used += r; + } +} + +int libxl__datareader_start(libxl__datareader_state *drs) +{ + int rc; + STATE_AO_GC(drs->ao); + + libxl__datareader_init(drs); + + rc = libxl__ev_fd_register(gc, &drs->toread, datareader_readable, + drs->readfd, POLLIN); + + return rc; +} diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index ae07857..943ffa1 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -2118,6 +2118,36 @@ void libxl__async_exec_init(libxl__async_exec_state *aes); int libxl__async_exec_start(libxl__gc *gc, libxl__async_exec_state *aes); bool libxl__async_exec_inuse(const libxl__async_exec_state *aes); +/*----- datareader: read data from one fd to buffer -----*/ + +typedef struct libxl__datareader_state libxl__datareader_state; + +/* + * real_size>=1 means all data was read + * real_size==0 means failure happened when reading, errnoval is valid, logged + * real_size==-1 means some other internal failure, errnoval not valid, logged + * In all cases reader is killed before calling this callback + */ +typedef void libxl__datareader_callback(libxl__egc *egc, + libxl__datareader_state *drs, ssize_t real_size, int errnoval); + +struct libxl__datareader_state { + /* caller must fill these in, and they must all remain valid */ + libxl__ao *ao; + int readfd; + ssize_t readsize; + /* for error msgs */ + const char *readwhat; + libxl__datareader_callback *callback; + /* It must contain enough space to store readsize bytes */ + void *buf; + /* remaining fields are private to datareader */ + libxl__ev_fd toread; + ssize_t used; +}; + +_hidden int libxl__datareader_start(libxl__datareader_state *drs); + /*----- device addition/removal -----*/ typedef struct libxl__ao_device libxl__ao_device; -- 1.9.3 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |