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

Reply via email to