# 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
|