[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] libxl: support multiple libxl__ev_fds for the same fd


  • To: xen-changelog@xxxxxxxxxxxxxxxxxxx
  • From: Xen patchbot-unstable <patchbot@xxxxxxx>
  • Date: Mon, 14 May 2012 16:32:32 +0000
  • Delivery-date: Mon, 14 May 2012 16:32:41 +0000
  • List-id: "Change log for Mercurial \(receive only\)" <xen-changelog.lists.xen.org>

# HG changeset patch
# User Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
# Date 1336759135 -3600
# Node ID 4e7a03e27a12e76e6a65f1e45ec991c600119ba1
# Parent  b675568d14b8f40b75a0db4dd8762c42c188961a
libxl: support multiple libxl__ev_fds for the same fd

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@xxxxxxxxxxxxx>
Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>

Changes since v6:
 * Fix typo
Committed-by: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
---


diff -r b675568d14b8 -r 4e7a03e27a12 tools/libxl/libxl_event.c
--- a/tools/libxl/libxl_event.c Fri May 11 18:58:55 2012 +0100
+++ b/tools/libxl/libxl_event.c Fri May 11 18:58:55 2012 +0100
@@ -639,10 +639,11 @@ static int beforepoll_internal(libxl__gc
 
 
     /*
-     * 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) {
@@ -663,14 +664,16 @@ static int beforepoll_internal(libxl__gc
         });
 
         /* 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;
         }
     }
 
@@ -681,8 +684,10 @@ static int beforepoll_internal(libxl__gc
             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++;
     });
@@ -710,7 +715,6 @@ static int beforepoll_internal(libxl__gc
             *timeout_upd = our_timeout;
     }
 
- out:
     return rc;
 }
 
@@ -732,24 +736,28 @@ static int afterpoll_check_fd(libxl__pol
                               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;
 }
@@ -1013,7 +1021,7 @@ int libxl__poller_init(libxl_ctx *ctx, l
 {
     int r, rc;
     p->fd_polls = 0;
-    p->fd_rindex = 0;
+    p->fd_rindices = 0;
 
     r = pipe(p->wakeup_pipe);
     if (r) {
@@ -1040,7 +1048,7 @@ void libxl__poller_dispose(libxl__poller
     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 -r b675568d14b8 -r 4e7a03e27a12 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h      Fri May 11 18:58:55 2012 +0100
+++ b/tools/libxl/libxl_internal.h      Fri May 11 18:58:55 2012 +0100
@@ -132,7 +132,11 @@ typedef void libxl__ev_fd_callback(libxl
    * 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: */
@@ -248,8 +252,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 */
 };

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.