xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Ian Jackson <ian.jackson@eu.citrix.com>
To: xen-devel@lists.xen.org
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Subject: [PATCH 02/24] libxl: support multiple libxl__ev_fds for the same fd
Date: Mon, 16 Apr 2012 18:17:44 +0100	[thread overview]
Message-ID: <1334596686-8479-3-git-send-email-ian.jackson@eu.citrix.com> (raw)
In-Reply-To: <1334596686-8479-1-git-send-email-ian.jackson@eu.citrix.com>

We need a slightly more sophisticated data structure to allow this,
where we record the slot not just for each fd but also for each
(fd,eventbit) where eventbit is POLLIN, POLLPRI, POLLOUT.

Document the new relaxed restriction.

Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>

Changes since v6:
 * Fix typo
---
 tools/libxl/libxl_event.c    |   62 +++++++++++++++++++++++------------------
 tools/libxl/libxl_internal.h |   10 +++++--
 2 files changed, 42 insertions(+), 30 deletions(-)

diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
index 5e1a207..149a4eb 100644
--- a/tools/libxl/libxl_event.c
+++ b/tools/libxl/libxl_event.c
@@ -635,10 +635,11 @@ static int beforepoll_internal(libxl__gc *gc, libxl__poller *poller,
 
 
     /*
-     * In order to be able to efficiently find the libxl__ev_fd
-     * for a struct poll during _afterpoll, we maintain a shadow
-     * data structure in CTX->fd_beforepolled: each slot in
-     * the fds array corresponds to a slot in fd_beforepolled.
+     * In order to be able to efficiently find the libxl__ev_fd for a
+     * struct poll during _afterpoll, we maintain a shadow data
+     * structure in CTX->fd_rindices: each fd corresponds to a slot in
+     * fd_rindices, and each element in the rindices is three indices
+     * into the fd array (for POLLIN, POLLPRI and POLLOUT).
      */
 
     if (*nfds_io) {
@@ -659,14 +660,16 @@ static int beforepoll_internal(libxl__gc *gc, libxl__poller *poller,
         });
 
         /* make sure our array is as big as *nfds_io */
-        if (poller->fd_rindex_allocd < maxfd) {
-            assert(maxfd < INT_MAX / sizeof(int) / 2);
-            int *newarray = realloc(poller->fd_rindex, sizeof(int) * maxfd);
-            if (!newarray) { rc = ERROR_NOMEM; goto out; }
-            memset(newarray + poller->fd_rindex_allocd, 0,
-                   sizeof(int) * (maxfd - poller->fd_rindex_allocd));
-            poller->fd_rindex = newarray;
-            poller->fd_rindex_allocd = maxfd;
+        if (poller->fd_rindices_allocd < maxfd) {
+            assert(ARRAY_SIZE_OK(poller->fd_rindices, maxfd));
+            poller->fd_rindices =
+                libxl__realloc(0, poller->fd_rindices,
+                               maxfd * sizeof(*poller->fd_rindices));
+            memset(poller->fd_rindices + poller->fd_rindices_allocd,
+                   0,
+                   (maxfd - poller->fd_rindices_allocd)
+                     * sizeof(*poller->fd_rindices));
+            poller->fd_rindices_allocd = maxfd;
         }
     }
 
@@ -677,8 +680,10 @@ static int beforepoll_internal(libxl__gc *gc, libxl__poller *poller,
             fds[used].fd = req_fd;
             fds[used].events = req_events;
             fds[used].revents = 0;
-            assert(req_fd < poller->fd_rindex_allocd);
-            poller->fd_rindex[req_fd] = used;
+            assert(req_fd < poller->fd_rindices_allocd);
+            if (req_events & POLLIN)  poller->fd_rindices[req_fd][0] = used;
+            if (req_events & POLLPRI) poller->fd_rindices[req_fd][1] = used;
+            if (req_events & POLLOUT) poller->fd_rindices[req_fd][2] = used;
         }
         used++;
     });
@@ -706,7 +711,6 @@ static int beforepoll_internal(libxl__gc *gc, libxl__poller *poller,
             *timeout_upd = our_timeout;
     }
 
- out:
     return rc;
 }
 
@@ -728,24 +732,28 @@ static int afterpoll_check_fd(libxl__poller *poller,
                               int fd, int events)
     /* returns mask of events which were requested and occurred */
 {
-    if (fd >= poller->fd_rindex_allocd)
+    if (fd >= poller->fd_rindices_allocd)
         /* added after we went into poll, have to try again */
         return 0;
 
-    int slot = poller->fd_rindex[fd];
+    int i, revents = 0;
+    for (i=0; i<3; i++) {
+        int slot = poller->fd_rindices[fd][i];
 
-    if (slot >= nfds)
-        /* stale slot entry; again, added afterwards */
-        return 0;
+        if (slot >= nfds)
+            /* stale slot entry; again, added afterwards */
+            continue;
 
-    if (fds[slot].fd != fd)
-        /* again, stale slot entry */
-        return 0;
+        if (fds[slot].fd != fd)
+            /* again, stale slot entry */
+            continue;
 
-    assert(!(fds[slot].revents & POLLNVAL));
+        assert(!(fds[slot].revents & POLLNVAL));
+        revents |= fds[slot].revents;
+    }
 
-    int revents = fds[slot].revents & (events | POLLERR | POLLHUP);
     /* we mask in case requested events have changed */
+    revents &= (events | POLLERR | POLLHUP);
 
     return revents;
 }
@@ -1009,7 +1017,7 @@ int libxl__poller_init(libxl_ctx *ctx, libxl__poller *p)
 {
     int r, rc;
     p->fd_polls = 0;
-    p->fd_rindex = 0;
+    p->fd_rindices = 0;
 
     r = pipe(p->wakeup_pipe);
     if (r) {
@@ -1036,7 +1044,7 @@ void libxl__poller_dispose(libxl__poller *p)
     if (p->wakeup_pipe[1] > 0) close(p->wakeup_pipe[1]);
     if (p->wakeup_pipe[0] > 0) close(p->wakeup_pipe[0]);
     free(p->fd_polls);
-    free(p->fd_rindex);
+    free(p->fd_rindices);
 }
 
 libxl__poller *libxl__poller_get(libxl_ctx *ctx)
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index af631fb..2ce4bb5 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -131,7 +131,11 @@ typedef void libxl__ev_fd_callback(libxl__egc *egc, libxl__ev_fd *ev,
    * events; otherwise revents contains only bits in events.  Contrary
    * to the documentation for poll(2), POLLERR and POLLHUP can occur
    * even if only POLLIN was set in events.  (POLLNVAL is a fatal
-   * error and will cause libxl event machinery to fail an assertion.) */
+   * error and will cause libxl event machinery to fail an assertion.)
+   *
+   * It is not permitted to listen for the same or overlapping events
+   * on the same fd using multiple different libxl__ev_fd's.
+   */
 struct libxl__ev_fd {
     /* caller should include this in their own struct */
     /* read-only for caller, who may read only when registered: */
@@ -257,8 +261,8 @@ struct libxl__poller {
     struct pollfd *fd_polls;
     int fd_polls_allocd;
 
-    int fd_rindex_allocd;
-    int *fd_rindex; /* see libxl_osevent_beforepoll */
+    int fd_rindices_allocd;
+    int (*fd_rindices)[3]; /* see libxl_osevent_beforepoll */
 
     int wakeup_pipe[2]; /* 0 means no fd allocated */
 };
-- 
1.7.2.5

  parent reply	other threads:[~2012-04-16 17:17 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-16 17:17 [PATCH v7 00/24] libxl: subprocess handling Ian Jackson
2012-04-16 17:17 ` [PATCH 01/24] libxl: handle POLLERR, POLLHUP, POLLNVAL properly Ian Jackson
2012-04-16 17:17 ` Ian Jackson [this message]
2012-04-16 17:17 ` [PATCH 03/24] libxl: event API: new facilities for waiting for subprocesses Ian Jackson
2012-04-16 17:17 ` [PATCH 04/24] autoconf: trim the configure script; use autoheader Ian Jackson
2012-04-17  9:18   ` Ian Campbell
2012-04-17 13:18     ` Ian Jackson
2012-04-17 13:22       ` Ian Campbell
2012-04-17 14:07         ` Roger Pau Monne
2012-04-16 17:17 ` [PATCH 05/24] autoconf: New test for openpty et al Ian Jackson
2012-04-17  9:20   ` Ian Campbell
2012-04-16 17:17 ` [PATCH 06/24] libxl: provide libxl__remove_file " Ian Jackson
2012-04-16 17:17 ` [PATCH 07/24] libxl: Introduce libxl__sendmsg_fds and libxl__recvmsg_fds Ian Jackson
2012-04-16 17:17 ` [PATCH 08/24] libxl: Clean up setdefault in do_domain_create Ian Jackson
2012-04-16 17:17 ` [PATCH 09/24] libxl: provide libxl__datacopier_* Ian Jackson
2012-04-17  9:37   ` Ian Campbell
2012-04-16 17:17 ` [PATCH 10/24] libxl: provide libxl__openpty_* Ian Jackson
2012-04-16 17:17 ` [PATCH 11/24] libxl: ao: Convert libxl_run_bootloader Ian Jackson
2012-04-16 17:17 ` [PATCH 12/24] libxl: make libxl_create_logfile const-correct Ian Jackson
2012-04-16 17:17 ` [PATCH 13/24] libxl: log bootloader output Ian Jackson
2012-04-16 17:17 ` [PATCH 14/24] libxl: Allow AO_GC and EGC_GC even if not used Ian Jackson
2012-04-16 17:17 ` [PATCH 15/24] libxl: remove ctx->waitpid_instead Ian Jackson
2012-04-17  9:40   ` Ian Campbell
2012-04-17 13:24     ` Ian Jackson
2012-04-16 17:17 ` [PATCH 16/24] libxl: change some structures to unit arrays Ian Jackson
2012-04-17  9:41   ` Ian Campbell
2012-04-16 17:17 ` [PATCH 17/24] libxl: ao: convert libxl__spawn_* Ian Jackson
2012-04-17 15:17   ` Ian Campbell
2012-04-17 17:03     ` Ian Jackson
2012-04-18 10:12       ` Ian Campbell
2012-04-18 10:52         ` Ian Jackson
2012-04-18 11:07           ` Ian Campbell
2012-04-16 17:18 ` [PATCH 18/24] libxl: make libxl_create run bootloader via callback Ian Jackson
2012-04-24 13:46   ` Ian Campbell
2012-04-24 13:54     ` Ian Jackson
2012-04-16 17:18 ` [PATCH 19/24] libxl: provide progress reporting for long-running operations Ian Jackson
2012-04-24 13:59   ` Ian Campbell
2012-04-25 13:38     ` Ian Jackson
2012-04-16 17:18 ` [PATCH 20/24] libxl: remove malloc failure handling from NEW_EVENT Ian Jackson
2012-04-24 14:01   ` Ian Campbell
2012-04-16 17:18 ` [PATCH 21/24] libxl: convert console callback to libxl_asyncprogress_how Ian Jackson
2012-04-24 14:05   ` Ian Campbell
2012-04-16 17:18 ` [PATCH 22/24] libxl: clarify definition of "slow" operation Ian Jackson
2012-04-24 14:06   ` Ian Campbell
2012-04-16 17:18 ` [PATCH 23/24] libxl: child processes cleanups Ian Jackson
2012-04-24 14:12   ` Ian Campbell
2012-04-24 14:27     ` Ian Jackson
2012-04-24 15:05       ` Ian Campbell
2012-04-24 15:07         ` Ian Campbell
2012-04-24 15:22     ` Ian Jackson
2012-04-24 15:32       ` Ian Campbell
2012-04-16 17:18 ` [PATCH 24/24] libxl: aborting bootloader invocation when domain dioes Ian Jackson
2012-04-24 14:18   ` Ian Campbell
2012-04-24 14:38     ` Ian Jackson
2012-04-24 15:08       ` Ian Campbell
2012-04-24 15:26         ` Ian Jackson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1334596686-8479-3-git-send-email-ian.jackson@eu.citrix.com \
    --to=ian.jackson@eu.citrix.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).