WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] Merge

# HG changeset patch
# User Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
# Date 1185285186 -3600
# Node ID cc48264ed64742a7c57704948ea04dcad438a015
# Parent  c585f993385c9dd6f61e27a9c6622adc8a8e50b1
# Parent  2f22450e716d037aa654e0486f4fe7722ad6b2bb
Merge
---
 tools/xenstore/talloc.c           |   18 ++++++
 tools/xenstore/xenstored_core.c   |   98 +++++++++++++++++++-------------------
 tools/xenstore/xenstored_domain.c |    9 +--
 3 files changed, 70 insertions(+), 55 deletions(-)

diff -r c585f993385c -r cc48264ed647 tools/xenstore/talloc.c
--- a/tools/xenstore/talloc.c   Tue Jul 24 14:52:16 2007 +0100
+++ b/tools/xenstore/talloc.c   Tue Jul 24 14:53:06 2007 +0100
@@ -97,6 +97,7 @@ struct talloc_chunk {
        struct talloc_chunk *next, *prev;
        struct talloc_chunk *parent, *child;
        struct talloc_reference_handle *refs;
+       unsigned int null_refs; /* references from null_context */
        talloc_destructor_t destructor;
        const char *name;
        size_t size;
@@ -189,6 +190,7 @@ void *_talloc(const void *context, size_
        tc->child = NULL;
        tc->name = NULL;
        tc->refs = NULL;
+       tc->null_refs = 0;
 
        if (context) {
                struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
@@ -225,7 +227,11 @@ void talloc_set_destructor(const void *p
 */
 void talloc_increase_ref_count(const void *ptr)
 {
-       talloc_reference(null_context, ptr);
+       struct talloc_chunk *tc;
+       if (ptr == NULL) return;
+
+       tc = talloc_chunk_from_ptr(ptr);
+       tc->null_refs++;
 }
 
 /*
@@ -285,6 +291,11 @@ static int talloc_unreference(const void
 
        if (context == NULL) {
                context = null_context;
+       }
+
+       if ((context == null_context) && tc->null_refs) {
+               tc->null_refs--;
+               return 0;
        }
 
        for (h=tc->refs;h;h=h->next) {
@@ -538,6 +549,11 @@ int talloc_free(void *ptr)
        }
 
        tc = talloc_chunk_from_ptr(ptr);
+
+       if (tc->null_refs) {
+               tc->null_refs--;
+               return -1;
+       }
 
        if (tc->refs) {
                talloc_reference_destructor(tc->refs);
diff -r c585f993385c -r cc48264ed647 tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c   Tue Jul 24 14:52:16 2007 +0100
+++ b/tools/xenstore/xenstored_core.c   Tue Jul 24 14:53:06 2007 +0100
@@ -299,10 +299,14 @@ static void set_fd(int fd, fd_set *set, 
 }
 
 
-static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock)
-{
-       struct connection *i;
+static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock,
+                         struct timeval **ptimeout)
+{
+       static struct timeval zero_timeout = { 0 };
+       struct connection *conn;
        int max = -1;
+
+       *ptimeout = NULL;
 
        FD_ZERO(inset);
        FD_ZERO(outset);
@@ -314,13 +318,19 @@ static int initialize_set(fd_set *inset,
        if (xce_handle != -1)
                set_fd(xc_evtchn_fd(xce_handle), inset, &max);
 
-       list_for_each_entry(i, &connections, list) {
-               if (i->domain)
-                       continue;
-               set_fd(i->fd, inset, &max);
-               if (!list_empty(&i->out_list))
-                       FD_SET(i->fd, outset);
-       }
+       list_for_each_entry(conn, &connections, list) {
+               if (conn->domain) {
+                       if (domain_can_read(conn) ||
+                           (domain_can_write(conn) &&
+                            !list_empty(&conn->out_list)))
+                               *ptimeout = &zero_timeout;
+               } else {
+                       set_fd(conn->fd, inset, &max);
+                       if (!list_empty(&conn->out_list))
+                               FD_SET(conn->fd, outset);
+               }
+       }
+
        return max;
 }
 
@@ -1709,6 +1719,7 @@ int main(int argc, char *argv[])
        bool no_domain_init = false;
        const char *pidfile = NULL;
        int evtchn_fd = -1;
+       struct timeval *timeout;
 
        while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RLVW:", options,
                                  NULL)) != -1) {
@@ -1850,17 +1861,16 @@ int main(int argc, char *argv[])
                evtchn_fd = xc_evtchn_fd(xce_handle);
 
        /* Get ready to listen to the tools. */
-       max = initialize_set(&inset, &outset, *sock, *ro_sock);
+       max = initialize_set(&inset, &outset, *sock, *ro_sock, &timeout);
 
        /* Tell the kernel we're up and running. */
        xenbus_notify_running();
 
        /* Main loop. */
-       /* FIXME: Rewrite so noone can starve. */
        for (;;) {
-               struct connection *i;
-
-               if (select(max+1, &inset, &outset, NULL, NULL) < 0) {
+               struct connection *conn, *old_conn;
+
+               if (select(max+1, &inset, &outset, NULL, timeout) < 0) {
                        if (errno == EINTR)
                                continue;
                        barf_perror("Select failed");
@@ -1882,41 +1892,31 @@ int main(int argc, char *argv[])
                if (evtchn_fd != -1 && FD_ISSET(evtchn_fd, &inset))
                        handle_event();
 
-               list_for_each_entry(i, &connections, list) {
-                       if (i->domain)
-                               continue;
-
-                       /* Operations can delete themselves or others
-                        * (xs_release): list is not safe after input,
-                        * so break. */
-                       if (FD_ISSET(i->fd, &inset)) {
-                               handle_input(i);
-                               break;
+               conn = list_entry(connections.next, typeof(*conn), list);
+               while (&conn->list != &connections) {
+                       talloc_increase_ref_count(conn);
+
+                       if (conn->domain) {
+                               if (domain_can_read(conn))
+                                       handle_input(conn);
+                               if (domain_can_write(conn) &&
+                                   !list_empty(&conn->out_list))
+                                       handle_output(conn);
+                       } else {
+                               if (FD_ISSET(conn->fd, &inset))
+                                       handle_input(conn);
+                               if (FD_ISSET(conn->fd, &outset))
+                                       handle_output(conn);
                        }
-                       if (FD_ISSET(i->fd, &outset)) {
-                               handle_output(i);
-                               break;
-                       }
-               }
-
-               /* Handle all possible I/O for domain connections. */
-       more:
-               list_for_each_entry(i, &connections, list) {
-                       if (!i->domain)
-                               continue;
-
-                       if (domain_can_read(i)) {
-                               handle_input(i);
-                               goto more;
-                       }
-
-                       if (domain_can_write(i) && !list_empty(&i->out_list)) {
-                               handle_output(i);
-                               goto more;
-                       }
-               }
-
-               max = initialize_set(&inset, &outset, *sock, *ro_sock);
+
+                       old_conn = conn;
+                       conn = list_entry(old_conn->list.next,
+                                         typeof(*conn), list);
+                       talloc_free(old_conn);
+               }
+
+               max = initialize_set(&inset, &outset, *sock, *ro_sock,
+                                    &timeout);
        }
 }
 
diff -r c585f993385c -r cc48264ed647 tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Tue Jul 24 14:52:16 2007 +0100
+++ b/tools/xenstore/xenstored_domain.c Tue Jul 24 14:53:06 2007 +0100
@@ -174,6 +174,8 @@ static int destroy_domain(void *_domain)
 
        if (domain->interface)
                munmap(domain->interface, getpagesize());
+
+       fire_watches(NULL, "@releaseDomain", false);
 
        return 0;
 }
@@ -197,7 +199,7 @@ static void domain_cleanup(void)
                                continue;
                }
                talloc_free(domain->conn);
-               notify = 1;
+               notify = 0; /* destroy_domain() fires the watch */
        }
 
        if (notify)
@@ -246,7 +248,6 @@ static struct domain *new_domain(void *c
 {
        struct domain *domain;
        int rc;
-
 
        domain = talloc(context, struct domain);
        domain->port = 0;
@@ -361,7 +362,7 @@ void do_introduce(struct connection *con
                /* Now domain belongs to its connection. */
                talloc_steal(domain->conn, domain);
 
-               fire_watches(conn, "@introduceDomain", false);
+               fire_watches(NULL, "@introduceDomain", false);
        } else if ((domain->mfn == mfn) && (domain->conn != conn)) {
                /* Use XS_INTRODUCE for recreating the xenbus event-channel. */
                if (domain->port)
@@ -413,8 +414,6 @@ void do_release(struct connection *conn,
        }
 
        talloc_free(domain->conn);
-
-       fire_watches(conn, "@releaseDomain", false);
 
        send_ack(conn, XS_RELEASE);
 }

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

<Prev in Thread] Current Thread [Next in Thread>