RPM Package Manager, CVS Repository http://rpm5.org/cvs/ ____________________________________________________________________________
Server: rpm5.org Name: Jeff Johnson Root: /v/rpm/cvs Email: j...@rpm5.org Module: rpm Date: 12-Jun-2017 05:06:21 Branch: rpm-5_4 Handle: 2017061203062100 Added files: (Branch: rpm-5_4) rpm/rpmio rpmev.h Modified files: (Branch: rpm-5_4) rpm/rpmio tmq.c Log: - WIP. Summary: Revision Changes Path 1.1.2.1 +101 -0 rpm/rpmio/rpmev.h 1.1.2.18 +534 -30 rpm/rpmio/tmq.c ____________________________________________________________________________ patch -p0 <<'@@ .' Index: rpm/rpmio/rpmev.h ============================================================================ $ cvs diff -u -r0 -r1.1.2.1 rpmev.h --- /dev/null 2017-06-12 05:05:45.000000000 +0200 +++ rpmev.h 2017-06-12 05:06:21.356371227 +0200 @@ -0,0 +1,101 @@ +#ifndef _H_RPMEV_ +#define _H_RPMEV_ + +/** + */ +extern int _rpmev_debug; + +typedef struct rpmev_s * rpmev; + +/** + */ +typedef enum rpmevType_e { + RPMEV_TYPE_UNKNOWN = 0, + RPMEV_TYPE_IO = 1, + RPMEV_TYPE_TIMER = 2, + RPMEV_TYPE_PERIODIC = 3, + RPMEV_TYPE_SIGNAL = 4, + RPMEV_TYPE_CHILD = 5, + RPMEV_TYPE_STAT = 6, + RPMEV_TYPE_IDLE = 7, + + RPMEV_TYPE_PREPARE = 8, + RPMEV_TYPE_CHECK = 9, + RPMEV_TYPE_FORK = 10, + RPMEV_TYPE_CLEANUP = 11, + RPMEV_TYPE_EMBED = 12, + RPMEV_TYPE_ASYNC = 13, +} rpmevType; +#define RPMEV_TYPE_MASK 0xf + +/** + */ +#define _KFB(n) (1U << (n)) +#define _MFB(n) (_KFB(n)) +#define RPMEV_FLAGS_TYPE_SHIFT 23 +typedef enum rpmevFlags_e { + RPMEV_FLAGS_NONE = 0, + /* bits 0-31 reserved */ +} rpmevFlags; +#undef _MFB +#undef _KFB + +#ifdef __cplusplus +extern "C" { +#endif + +/** + */ +#if defined(_RPMEV_INTERNAL) +struct rpmev_s { + struct rpmioItem_s _item; /*!< usage mutex and pool identifier. */ + + rpmevType evtype; + union ev_any_watcher evw; +#ifdef NOTYET + void (*evcb) (void *_w, int revents); +#else + void *evcb; +#endif +}; + +#endif /* _RPMEV_INTERNAL */ + +/** + * Unreference a ev wrapper instance. + * @param ev ev wrapper + * @return NULL on last dereference + */ +rpmev rpmevUnlink (rpmev ev); +#define rpmevUnlink(_ev) \ + ((rpmev)rpmioUnlinkPoolItem((rpmioItem)(_ev), __FUNCTION__, __FILE__, __LINE__)) + +/** + * Reference a ev wrapper instance. + * @param ev ev wrapper + * @return new ev wrapper reference + */ +rpmev rpmevLink (rpmev ev); +#define rpmevLink(_ev) \ + ((rpmev)rpmioLinkPoolItem((rpmioItem)(_ev), __FUNCTION__, __FILE__, __LINE__)) + +/** + * Destroy a ev wrapper. + * @param ev ev wrapper + * @return NULL on last dereference + */ +rpmev rpmevFree(rpmev ev); +#define rpmevFree(_ev) \ + ((rpmev)rpmioFreePoolItem((rpmioItem)(_ev), __FUNCTION__, __FILE__, __LINE__)) + +/** + * Create a ev wrapper. + * @return ev wrapper + */ +rpmev rpmevNew(rpmevType evtype, void * evcb); + +#ifdef __cplusplus +} +#endif + +#endif /* _H_RPMEV_ */ @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/tmq.c ============================================================================ $ cvs diff -u -r1.1.2.17 -r1.1.2.18 tmq.c --- rpm/rpmio/tmq.c 10 Jun 2017 21:26:43 -0000 1.1.2.17 +++ rpm/rpmio/tmq.c 12 Jun 2017 03:06:21 -0000 1.1.2.18 @@ -23,15 +23,20 @@ #if defined(HAVE_SYS_SEM_H) # include <sys/sem.h> -#if _SEM_SEMUN_UNDEFINED - union semun - { - int val; - struct semid_ds *buf; - unsigned short int *array; - struct seminfo *__buf; - }; -#endif +# if _SEM_SEMUN_UNDEFINED +# if defined(HAVE_LINUX_SEM_H_XXX) +# include <linux/sem.h> +# else + union semun + { + int val; + struct semid_ds *buf; + unsigned short *array; + struct seminfo *__buf; + void *__pad; + }; +# endif +# endif #endif #if defined(HAVE_SYS_SHM_H) @@ -95,6 +100,8 @@ if (_debug || _rpmmsq_debug || _rpmio_debug) \ fprintf(stderr, _fmt, __VA_ARGS__) +#define Z(_rc) assert((_rc) == 0) + /*==============================================================*/ static int Shm_open(const char *path, int oflags, mode_t mode) { @@ -879,7 +886,7 @@ int IO_queue_init(int maxevents, io_context_t *ctxp) { int rc = io_queue_init(maxevents, ctxp); -fprintf(stderr, "<-- %s(%d,%p) rc %d\n", __FUNCTION__, maxevents, ctxp, rc); +SPEW("<-- %s(%d,%p) rc %d\n", __FUNCTION__, maxevents, ctxp, rc); return rc; } @@ -887,7 +894,7 @@ int IO_queue_release(io_context_t ctx) { int rc = io_queue_release(ctx); -fprintf(stderr, "<-- %s(%p) rc %d\n", __FUNCTION__, ctx, rc); +SPEW("<-- %s(%p) rc %d\n", __FUNCTION__, ctx, rc); return rc; } @@ -895,7 +902,7 @@ int IO_queue_run(io_context_t ctx) { int rc = io_queue_run(ctx); -fprintf(stderr, "<-- %s(%p) rc %d\n", __FUNCTION__, ctx, rc); +SPEW("<-- %s(%p) rc %d\n", __FUNCTION__, ctx, rc); return rc; } @@ -903,7 +910,7 @@ int IO_setup(int maxevents, io_context_t *ctxp) { int rc = io_setup(maxevents, ctxp); -fprintf(stderr, "<-- %s(%d,%p) rc %d\n", __FUNCTION__, maxevents, ctxp, rc); +SPEW("<-- %s(%d, %p) rc %d\n", __FUNCTION__, maxevents, ctxp, rc); return rc; } @@ -911,7 +918,7 @@ int IO_destroy(io_context_t ctx) { int rc = io_destroy(ctx); -fprintf(stderr, "<-- %s(%p) rc %d\n", __FUNCTION__, ctx, rc); +SPEW("<-- %s(%p) rc %d\n", __FUNCTION__, ctx, rc); return rc; } @@ -919,7 +926,7 @@ int IO_submit(io_context_t ctx, long nr, struct iocb *iocbs[]) { int rc = io_submit(ctx, nr, iocbs); -fprintf(stderr, "<-- %s(%p,%ld,%p) rc %d\n", __FUNCTION__, ctx, nr, iocbs, rc); +SPEW("<-- %s(%p, %ld, %p) rc %d\n", __FUNCTION__, ctx, nr, iocbs, rc); return rc; } @@ -927,7 +934,7 @@ int IO_cancel(io_context_t ctx, struct iocb *iocb, struct io_event *evt) { int rc = io_cancel(ctx, iocb, evt); -fprintf(stderr, "<-- %s(%p,%p,%p) rc %d\n", __FUNCTION__, ctx, iocb, evt, rc); +SPEW("<-- %s(%p, %p, %p) rc %d\n", __FUNCTION__, ctx, iocb, evt, rc); return rc; } @@ -936,14 +943,14 @@ struct io_event *events, struct timespec *timeout) { int rc = io_getevents(ctx, min_nr, nr, events, timeout); -fprintf(stderr, "<-- %s(%p,%ld,%ld,%p,%p) rc %d\n", __FUNCTION__, ctx, min_nr, nr, events, timeout, rc); +SPEW("<-- %s(%p, %ld, %ld, %p, %p) rc %d\n", __FUNCTION__, ctx, min_nr, nr, events, timeout, rc); return rc; } static void IO_set_callback(struct iocb *iocb, io_callback_t cb) { -fprintf(stderr, "--> %s(%p,%p)\n", __FUNCTION__, iocb, cb); +SPEW("--> %s(%p, %p)\n", __FUNCTION__, iocb, cb); io_set_callback(iocb, cb); } @@ -951,7 +958,7 @@ void IO_prep_pread(struct iocb *iocb, int fd, void *buf, size_t count, long long offset) { -fprintf(stderr, "--> %s(%p,%d,%p[%zu],%lld)\n", __FUNCTION__, iocb, fd, buf, count, offset); +SPEW("--> %s(%p, %d, %p[%zu], %lld)\n", __FUNCTION__, iocb, fd, buf, count, offset); io_prep_pread(iocb, fd, buf, count, offset); } @@ -959,7 +966,7 @@ void IO_prep_pwrite(struct iocb *iocb, int fd, void *buf, size_t count, long long offset) { -fprintf(stderr, "--> %s(%p,%d,%p[%zu],%lld)\n", __FUNCTION__, iocb, fd, buf, count, offset); +SPEW("--> %s(%p, %d, %p[%zu], %lld)\n", __FUNCTION__, iocb, fd, buf, count, offset); io_prep_pwrite(iocb, fd, buf, count, offset); } @@ -967,21 +974,21 @@ void IO_prep_preadv(struct iocb *iocb, int fd, const struct iovec *iov, int iovcnt, long long offset) { -fprintf(stderr, "--> %s(%p,%d,%p[%u],%lld)\n", __FUNCTION__, iocb, fd, iov, iovcnt, offset); +SPEW("--> %s(%p, %d, %p[%u], %lld)\n", __FUNCTION__, iocb, fd, iov, iovcnt, offset); } static void IO_prep_pwritev(struct iocb *iocb, int fd, const struct iovec *iov, int iovcnt, long long offset) { -fprintf(stderr, "--> %s(%p,%d,%p[%u],%lld)\n", __FUNCTION__, iocb, fd, iov, iovcnt, offset); +SPEW("--> %s(%p, %d, %p[%u], %lld)\n", __FUNCTION__, iocb, fd, iov, iovcnt, offset); io_prep_pwritev(iocb, fd, iov, iovcnt, offset); } static void IO_prep_poll(struct iocb *iocb, int fd, int events) { -fprintf(stderr, "--> %s(%p,%d,%d)\n", __FUNCTION__, iocb, fd, events); +SPEW("--> %s(%p, %d, %d)\n", __FUNCTION__, iocb, fd, events); io_prep_poll(iocb, fd, events); } @@ -990,14 +997,14 @@ int fd, int events) { int rc = io_poll(ctx, iocb, cb, fd, events); -fprintf(stderr, "<-- %s(%p,%p,%p,%d,%d) rc %d\n", __FUNCTION__, ctx, iocb, cb, fd, events, rc); +SPEW("<-- %s(%p, %p, %p, %d, %d) rc %d\n", __FUNCTION__, ctx, iocb, cb, fd, events, rc); return rc; } static void IO_prep_fsync(struct iocb *iocb, int fd) { -fprintf(stderr, "--> %s(%p,%d)\n", __FUNCTION__, iocb, fd); +SPEW("--> %s(%p, %d)\n", __FUNCTION__, iocb, fd); io_prep_fsync(iocb, fd); } @@ -1005,14 +1012,14 @@ int IO_fsync(io_context_t ctx, struct iocb *iocb, io_callback_t cb, int fd) { int rc = io_fsync(ctx, iocb, cb, fd); -fprintf(stderr, "<-- %s(%p,%p,%p,%d) rc %d\n", __FUNCTION__, ctx, iocb, cb, fd, rc); +SPEW("<-- %s(%p, %p, %p, %d) rc %d\n", __FUNCTION__, ctx, iocb, cb, fd, rc); return rc; } static void IO_prep_fdsync(struct iocb *iocb, int fd) { -fprintf(stderr, "--> %s(%p,%d)\n", __FUNCTION__, iocb, fd); +SPEW("--> %s(%p, %d)\n", __FUNCTION__, iocb, fd); io_prep_fdsync(iocb, fd); } @@ -1020,23 +1027,519 @@ int IO_fdsync(io_context_t ctx, struct iocb *iocb, io_callback_t cb, int fd) { int rc = io_fdsync(ctx, iocb, cb, fd); -fprintf(stderr, "<-- %s(%p,%p,%p,%d) rc %d\n", __FUNCTION__, ctx, iocb, cb, fd, rc); +SPEW("<-- %s(%p, %p, %p, %d) rc %d\n", __FUNCTION__, ctx, iocb, cb, fd, rc); return rc; } static void IO_set_eventfd(struct iocb *iocb, int eventfd) { -fprintf(stderr, "--> %s(%p,%d)\n", __FUNCTION__, iocb, eventfd); +SPEW("--> %s(%p, %d)\n", __FUNCTION__, iocb, eventfd); io_set_eventfd(iocb, eventfd); } /*==============================================================*/ +static +void LAIO_done(io_context_t ctx, struct iocb *iocb, long res, long res2) +{ +SPEW("--> %s(%p, %p, %ld, %ld)\n", __FUNCTION__, ctx, iocb, res, res2); +} + static int doLAIO(ARGV_t av, int ac) { int rc = -2; /* assume failure */ + io_context_t ctx = NULL; + struct iocb cb = {}; + FD_t fd = Fopen("foo", "rbD"); +assert(fd); + int fdno = Fileno(fd); + size_t nb = BUFSIZ; + char *b = NULL; + + rc = posix_memalign((void **) &b, 512, BUFSIZ); + if (rc < 0) { + perror("posix_memalign"); + goto exit; + } + + unsigned _nr_events = 10; + rc = IO_setup(_nr_events, &ctx); + if (rc < 0) { + perror("IO_setup"); + goto exit; + } + + long long _off = 0; + io_prep_pread(&cb, fdno, b, nb, _off); + io_set_callback(&cb, LAIO_done); + + struct iocb * iocbs[] = { &cb }; + size_t niocbs = (sizeof(iocbs)/sizeof(iocbs[0])); + rc = IO_submit(ctx, niocbs, iocbs); + if (rc != (int)niocbs) { + perror("IO_submit"); + goto exit; + } + + long _min_nr = 0; + long _nr = 1; + struct io_event _events[1] = {}; + int nwaits = 0; + do { + nwaits++; + struct timespec ts = { 0, 100*1000*1000 }; + nanosleep(&ts, NULL); + sched_yield(); + + struct timespec * _timeout = NULL; + rc = IO_getevents(ctx, _min_nr, _nr, _events, _timeout); + if (rc < 0) { + perror("IO_getevents"); + goto exit; + } + for (int i = 0; i < rc; i++) { + struct io_event * ev = &_events[i]; + io_callback_t cb = (io_callback_t)ev->data; + if (cb == NULL) + continue; + struct iocb *iocb = ev->obj; + cb(ctx, iocb, ev->res, ev->res2); + } + + } while (rc == 0); + + struct io_event * ev = &_events[0]; + int nread = ev->res; +fprintf(stderr, "*** nwaits %d data %p obj %p res %lu res2 %lu\n", nwaits, ev->data, ev->obj, ev->res, ev->res2); +fprintf(stderr, "%.*s", nread, b); rc = 0; + +exit: + if (ctx) { + rc = IO_destroy(ctx); + if (rc < 0) + perror("IO_destroy"); + } + if (fd) { + rc = Fclose(fd); + if (rc < 0) + perror("Fclose"); + } + if (b) + free(b); + + return rc; +} + +/*==============================================================*/ +#if defined(HAVE_EV_H) +# include <ev.h> +#endif + +#define _RPMEV_INTERNAL +#include <rpmev.h> + +static unsigned rpmioEV = 0; +struct poptOption rpmioEVTable[] = { + { "read", '\0', POPT_BIT_SET, &rpmioEV, EV_READ, + N_("read"), N_("EV_READ") }, + { "write", '\0', POPT_BIT_SET, &rpmioEV, EV_WRITE, + N_("write"), N_("EV_WRITE") }, + { "internal", '\0', POPT_BIT_SET, &rpmioEV, EV__IOFDSET, + N_("internal"), N_("EV__IOFDSET") }, + { "timer", '\0', POPT_BIT_SET, &rpmioEV, EV_TIMER, + N_("timer"), N_("EV_TIMER") }, + { "periodic", '\0', POPT_BIT_SET, &rpmioEV, EV_PERIODIC, + N_("periodic"), N_("EV_PERIODIC") }, + { "signal", '\0', POPT_BIT_SET, &rpmioEV, EV_SIGNAL, + N_("signal"), N_("EV_SIGNAL") }, + { "child", '\0', POPT_BIT_SET, &rpmioEV, EV_CHILD, + N_("child"), N_("EV_CHILD") }, + { "stat", '\0', POPT_BIT_SET, &rpmioEV, EV_STAT, + N_("stat"), N_("EV_STAT") }, + { "idle", '\0', POPT_BIT_SET, &rpmioEV, EV_IDLE, + N_("idle"), N_("EV_IDLE") }, + { "prepare", '\0', POPT_BIT_SET, &rpmioEV, EV_PREPARE, + N_("prepare"), N_("EV_PREPARE") }, + { "check", '\0', POPT_BIT_SET, &rpmioEV, EV_CHECK, + N_("check"), N_("EV_CHECK") }, + { "embed", '\0', POPT_BIT_SET, &rpmioEV, EV_EMBED, + N_("embed"), N_("EV_EMBED") }, + { "fork", '\0', POPT_BIT_SET, &rpmioEV, EV_FORK, + N_("fork"), N_("EV_FORK") }, + { "cleanup", '\0', POPT_BIT_SET, &rpmioEV, EV_CLEANUP, + N_("cleanup"), N_("EV_CLEANUP") }, + { "async", '\0', POPT_BIT_SET, &rpmioEV, EV_ASYNC, + N_("async"), N_("EV_ASYNC") }, + { "custom", '\0', POPT_BIT_SET, &rpmioEV, EV_CUSTOM, + N_("custom"), N_("EV_CUSTOM") }, + { "error", '\0', POPT_BIT_SET, &rpmioEV, EV_ERROR, + N_("error"), N_("EV_ERROR") }, + POPT_TABLEEND +}; + +static unsigned rpmioEVFLAG = 0; +struct poptOption rpmioEVFLAGTable[] = { + { "env", '\0', POPT_BIT_CLR|POPT_ARGFLAG_TOGGLE, &rpmioEVFLAG, EVFLAG_NOENV, + N_("env"), N_("EVFLAG_NOENV") }, + { "forkcheck", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE, &rpmioEVFLAG, EVFLAG_FORKCHECK, + N_("forkcheck"), N_("EVFLAG_FORKCHECK") }, + { "inotify", '\0', POPT_BIT_CLR|POPT_ARGFLAG_TOGGLE, &rpmioEVFLAG, EVFLAG_NOINOTIFY, + N_("inotify"), N_("EVFLAG_NOINOTIFY") }, + { "signalfd", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE, &rpmioEVFLAG, EVFLAG_SIGNALFD, + N_("signalfd"), N_("EVFLAG_SIGNALFD") }, + { "sigmask", '\0', POPT_BIT_CLR|POPT_ARGFLAG_TOGGLE, &rpmioEVFLAG, EVFLAG_NOSIGMASK, + N_("sigmask"), N_("EVFLAG_NOSIGMASK") }, + POPT_TABLEEND +}; + +static unsigned rpmioEVBACKEND = 0; +struct poptOption rpmioEVBACKENDTable[] = { + { "select", '\0', POPT_BIT_SET, &rpmioEVBACKEND, EVBACKEND_SELECT, + N_("select"), N_("EVBACKEND_SELECT") }, + { "poll", '\0', POPT_BIT_SET, &rpmioEVBACKEND, EVBACKEND_POLL, + N_("poll"), N_("EVBACKEND_POLL") }, + { "epoll", '\0', POPT_BIT_SET, &rpmioEVBACKEND, EVBACKEND_EPOLL, + N_("epoll"), N_("EVBACKEND_EPOLL") }, + { "kqueue", '\0', POPT_BIT_SET, &rpmioEVBACKEND, EVBACKEND_KQUEUE, + N_("kqueue"), N_("EVBACKEND_KQUEUE") }, + { "devpoll", '\0', POPT_BIT_SET, &rpmioEVBACKEND, EVBACKEND_DEVPOLL, + N_("devpoll"), N_("EVBACKEND_DEVPOLL") }, + { "port", '\0', POPT_BIT_SET, &rpmioEVBACKEND, EVBACKEND_PORT, + N_("port"), N_("EVBACKEND_PORT") }, + POPT_TABLEEND +}; + +/*==============================================================*/ +/* every watcher type has its own typedef'd struct */ +/* with the name ev_TYPE */ + +/* all watcher callbacks have a similar signature */ + +#define NS(_X) rpmev##_X +#define NScb(_X_) rpmev##_X_##_cb + +#define rpmevCBproto(_T, _N_) \ + void NScb(_N_) (EV_P_ ev_##_T *w, int revents) + +static +void rpmevDump(const char *msg, rpmev ev, FILE *fp) +{ + if (fp == NULL) fp = stderr; + if (msg) fprintf(stderr, "========================= %s(%p)\n", msg, ev); + if (ev) { +#define PRINT(_fmt, _foo) \ + { fprintf(fp, "%25s: %"#_fmt"\n", #_foo, ev->_foo); } + PRINT(d, evw.w.active); + PRINT(d, evw.w.pending); + PRINT(p, evw.w.data); + PRINT(p, evw.w.cb); +#undef PRINT + + } +} + +#define RPMEV_MAX_ALLOC 64 +static rpmev evs[RPMEV_MAX_ALLOC]; +static int nevs = 0; + +rpmev rpmevNew(rpmevType evtype, void *evcb) +{ + rpmev ev = NULL; + if (nevs < RPMEV_MAX_ALLOC) { + ev = xcalloc(1, sizeof(*ev)); /* XXX xmalloc */ + ev_watcher * w = &ev->evw.w; + ev_init(w, evcb); + ev->evtype = evtype; + ev->evcb = evcb; /* XXX snarf from ev->evw.w. */ + evs[nevs++] = ev; + } +SPEW("<-- %s(%d,%p) ev %p\n", __FUNCTION__, evtype, evcb, ev); + return ev; +} + +/* --- */ +static rpmevCBproto(child, Child) { + rpmev ev = (rpmev) (((struct rpmioItem_s *)w) - 1); + (void)ev; + { char *rstr = rpmioB2N(rpmioEVTable, revents); + SPEW("--> %s(%p, %s) pid %u status %u\n", __FUNCTION__, w, rstr, w->rpid, w->rstatus); + rstr = _free(rstr); + } + ev_child_stop (EV_A_ w); +} + +static +int rpmevStart(void) +{ + int rc; +SPEW("--> %s()\n", __FUNCTION__); + pid_t pid = fork(); + if (pid < 0) { + rc = -1; + exit(rc); + } else if (pid == 0) { + sleep(2); + rc = 42; + exit(rc); + } else { + if (nevs < RPMEV_MAX_ALLOC) { + rpmev ev = rpmevNew(RPMEV_TYPE_CHILD, NScb(Child)); + ev_child * w = &ev->evw.child; + w->pid = 0; + w->flags = 0; /** XXX 0=terminate, 1=stop/continue */ + ev_child_start (EV_DEFAULT_ w); + } + rc = 0; + } +SPEW("<-- %s() rc %d\n", __FUNCTION__, rc); + return rc; +} + +/* --- */ +static void NScb(Stdin)(EV_P_ ev_io *w, int revents) +{ + rpmev ev = (rpmev) (((struct rpmioItem_s *)w) - 1); + (void)ev; + { char *rstr = rpmioB2N(rpmioEVTable, revents); + SPEW("--> %s(%p, %s) fd %d events 0x%x\n", __FUNCTION__, w, rstr, w->fd, w->events); + rstr = _free(rstr); + } + /* for one-shot events, one must manually stop the watcher */ + /* with its corresponding stop function. */ + ev_io_stop(EV_A_ w); + + /* this causes all nested ev_loop's to stop iterating */ + ev_unloop(EV_A_ EVUNLOOP_ALL); +} +/* --- */ +static void NScb(Timeout)(EV_P_ ev_timer *w, int revents) +{ + rpmev ev = (rpmev) (((struct rpmioItem_s *)w) - 1); + (void)ev; + { char *rstr = rpmioB2N(rpmioEVTable, revents); + SPEW("--> %s(%p, %s) repeat %f\n", __FUNCTION__, w, rstr, w->repeat); + rstr = _free(rstr); + } +#ifdef DYING + /* this causes the innermost ev_loop to stop iterating */ + ev_unloop(EV_A_ EVUNLOOP_ONE); +#endif + w->repeat = 5.5; + ev_timer_again(EV_A_ w); +} + +/* --- */ +static rpmevCBproto(periodic, Periodic) +{ + rpmev ev = (rpmev) (((struct rpmioItem_s *)w) - 1); + (void)ev; + { char *rstr = rpmioB2N(rpmioEVTable, revents); + SPEW("--> %s(%p, %s) offset %f interval %f reschedule_cb %p\n", __FUNCTION__, w, rstr, w->offset, w->interval, w->reschedule_cb); + rstr = _free(rstr); + } + rpmevStart(); +} + +/* --- */ +static rpmevCBproto(signal, Signal) +{ + rpmev ev = (rpmev) (((struct rpmioItem_s *)w) - 1); + (void)ev; + { char *rstr = rpmioB2N(rpmioEVTable, revents); + SPEW("--> %s(%p, %s) signum %d\n", __FUNCTION__, w, rstr, w->signum); + rstr = _free(rstr); + } +} + +/* --- */ +static rpmevCBproto(stat, Stat) +{ + rpmev ev = (rpmev) (((struct rpmioItem_s *)w) - 1); + (void)ev; + { char *rstr = rpmioB2N(rpmioEVTable, revents); + SPEW("--> %s(%p, %s) path %s wd %d\n", __FUNCTION__, w, rstr, w->path, w->wd); + rstr = _free(rstr); + } +} + +/* --- */ +static rpmevCBproto(idle, Idle) +{ + rpmev ev = (rpmev) (((struct rpmioItem_s *)w) - 1); + (void)ev; +#ifdef NOISY + { char *rstr = rpmioB2N(rpmioEVTable, revents); + SPEW("--> %s(%p, %s)\n", __FUNCTION__, w, rstr); + rstr = _free(rstr); + } +#endif + struct timespec ts = { 0, 10*1000*1000 }; + nanosleep(&ts, NULL); + sched_yield(); +} + +/* --- */ +static rpmevCBproto(prepare, Prepare) +{ + rpmev ev = (rpmev) (((struct rpmioItem_s *)w) - 1); + (void)ev; + { char *rstr = rpmioB2N(rpmioEVTable, revents); + SPEW("--> %s(%p, %s)\n", __FUNCTION__, w, rstr); + rstr = _free(rstr); + } +} + +/* --- */ +static rpmevCBproto(check, Check) +{ + rpmev ev = (rpmev) (((struct rpmioItem_s *)w) - 1); + (void)ev; + { char *rstr = rpmioB2N(rpmioEVTable, revents); + SPEW("--> %s(%p, %s)\n", __FUNCTION__, w, rstr); + rstr = _free(rstr); + } +} + +/* --- */ +static rpmevCBproto(fork, Fork) +{ + rpmev ev = (rpmev) (((struct rpmioItem_s *)w) - 1); + (void)ev; + { char *rstr = rpmioB2N(rpmioEVTable, revents); + SPEW("--> %s(%p, %s)\n", __FUNCTION__, w, rstr); + rstr = _free(rstr); + } +} + +/* --- */ +static rpmevCBproto(cleanup, Cleanup) +{ + rpmev ev = (rpmev) (((struct rpmioItem_s *)w) - 1); + (void)ev; + { char *rstr = rpmioB2N(rpmioEVTable, revents); + SPEW("--> %s(%p, %s)\n", __FUNCTION__, w, rstr); + rstr = _free(rstr); + } +} + +/* --- */ +static rpmevCBproto(embed, Embed) +{ + rpmev ev = (rpmev) (((struct rpmioItem_s *)w) - 1); + (void)ev; + { char *rstr = rpmioB2N(rpmioEVTable, revents); + SPEW("--> %s(%p, %s)\n", __FUNCTION__, w, rstr); + rstr = _free(rstr); + } +} + +/* --- */ +static rpmevCBproto(async, Async) +{ + rpmev ev = (rpmev) (((struct rpmioItem_s *)w) - 1); + (void)ev; + { char *rstr = rpmioB2N(rpmioEVTable, revents); + SPEW("--> %s(%p, %s)\n", __FUNCTION__, w, rstr); + rstr = _free(rstr); + } +} + +static int doEV(ARGV_t av, int ac) +{ + int rc = 0; + +SPEW(" version: %u.%u\n", ev_version_major(), ev_version_minor()); + +char *rstr = NULL; +unsigned mask = 0; +mask = ev_supported_backends(); +rstr = rpmioB2N(rpmioEVBACKENDTable, mask); +SPEW(" supported: %s\n", rstr); +rstr = _free(rstr); + +mask = ev_recommended_backends(); +rstr = rpmioB2N(rpmioEVBACKENDTable, mask); +SPEW("recommended: %s\n", rstr); +rstr = _free(rstr); + +mask = ev_embeddable_backends(); +rstr = rpmioB2N(rpmioEVBACKENDTable, mask); +SPEW(" embeddable: %s\n", rstr); +rstr = _free(rstr); + +SPEW(" time: %f\n", ev_time()); + + /* use the default event loop unless you have special needs */ + struct ev_loop *loop = ev_default_loop(EVFLAG_AUTO); + rpmev ev = NULL; + + /* initialise an io watcher, then start it */ + /* this one will watch for stdin to become readable */ + ev = rpmevNew(RPMEV_TYPE_IO, NScb(Stdin)); +rpmevDump(__FUNCTION__, ev, NULL); + { ev_io * w = &ev->evw.io; + w->fd = STDIN_FILENO; + w->events = EV_READ; + ev_io_start(loop, w); + } + + /* initialise a timer watcher, then start it */ + /* simple non-repeating 5.5 second timeout */ + ev = rpmevNew(RPMEV_TYPE_TIMER, NScb(Timeout)); + { ev_timer * w = &ev->evw.timer; + w->repeat = 5.5; + ev_timer_start(loop, w); + } + + ev = rpmevNew(RPMEV_TYPE_PERIODIC, NScb(Periodic)); + { ev_periodic * w = &ev->evw.periodic; + w->offset = 0.0; + w->interval = 11.0; + w->reschedule_cb = NULL; + ev_periodic_start(loop, w); + } + + ev = rpmevNew(RPMEV_TYPE_SIGNAL, NScb(Signal)); + { ev_signal * w = &ev->evw.signal; + w->signum = SIGUSR1; + ev_signal_start(loop, w); + } + + ev = rpmevNew(RPMEV_TYPE_CHILD, NScb(Child)); + { ev_child * w = &ev->evw.child; + w->pid = 0; + w->flags = 0; /** XXX 0=terminate, 1=stop/continue */ + } + + ev = rpmevNew(RPMEV_TYPE_STAT, NScb(Stat)); + { ev_stat * w = &ev->evw.stat; + w->interval = 0; /* XXX 0=recommended ~5s, must be >0.1 */ + w->path = "/X/src/wdj54/rpmio/tmq"; + ev_stat_start(loop, w); + } + + ev = rpmevNew(RPMEV_TYPE_IDLE, NScb(Idle)); + { ev_idle * w = &ev->evw.idle; + ev_idle_start(loop, w); + } + + ev = rpmevNew(RPMEV_TYPE_PREPARE, NScb(Prepare)); + ev = rpmevNew(RPMEV_TYPE_CHECK, NScb(Check)); + ev = rpmevNew(RPMEV_TYPE_FORK, NScb(Fork)); + ev = rpmevNew(RPMEV_TYPE_CLEANUP, NScb(Cleanup)); + ev = rpmevNew(RPMEV_TYPE_EMBED, NScb(Embed)); + ev = rpmevNew(RPMEV_TYPE_ASYNC, NScb(Async)); + + /* now wait for events to arrive */ + ev_run(loop, 0); + + /* unloop was called, so exit */ + + for (int i = 0; i < nevs; i++) { + evs[i] = _free(evs[i]); + } return rc; } @@ -1093,11 +1596,12 @@ if (qname == NULL) qname = xstrdup("rpm"); - switch (1) { + switch (5) { case 1: ec = doSHM(av, ac); break; case 2: ec = doMSQ(av, ac); break; case 3: ec = doTIMER(av, ac); break; case 4: ec = doLAIO(av, ac); break; + case 5: ec = doEV(av, ac); break; } qname = _free(qname); @@ . ______________________________________________________________________ RPM Package Manager http://rpm5.org CVS Sources Repository rpm-cvs@rpm5.org