mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
Merge
This commit is contained in:
commit
d55594ec24
3 files changed
+64
-49
No files matched your search
+17
-1
@@ -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_t 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 *ptr, int (*destructor)(void *))
|
||||
*/
|
||||
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++;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -287,6 +293,11 @@ static int talloc_unreference(const void *context, const void *ptr)
|
||||
context = null_context;
|
||||
}
|
||||
|
||||
if ((context == null_context) && tc->null_refs) {
|
||||
tc->null_refs--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (h=tc->refs;h;h=h->next) {
|
||||
struct talloc_chunk *p = talloc_parent_chunk(h);
|
||||
if (p == NULL) {
|
||||
@@ -539,6 +550,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);
|
||||
return -1;
|
||||
|
||||
@@ -299,11 +299,15 @@ static void set_fd(int fd, fd_set *set, int *max)
|
||||
}
|
||||
|
||||
|
||||
static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock)
|
||||
static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock,
|
||||
struct timeval **ptimeout)
|
||||
{
|
||||
struct connection *i;
|
||||
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, fd_set *outset, int sock, int ro_sock)
|
||||
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;
|
||||
struct connection *conn, *old_conn;
|
||||
|
||||
if (select(max+1, &inset, &outset, NULL, NULL) < 0) {
|
||||
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;
|
||||
conn = list_entry(connections.next, typeof(*conn), list);
|
||||
while (&conn->list != &connections) {
|
||||
talloc_increase_ref_count(conn);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
if (FD_ISSET(i->fd, &outset)) {
|
||||
handle_output(i);
|
||||
break;
|
||||
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);
|
||||
}
|
||||
|
||||
old_conn = conn;
|
||||
conn = list_entry(old_conn->list.next,
|
||||
typeof(*conn), list);
|
||||
talloc_free(old_conn);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
max = initialize_set(&inset, &outset, *sock, *ro_sock,
|
||||
&timeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -175,6 +175,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)
|
||||
@@ -247,7 +249,6 @@ static struct domain *new_domain(void *context, unsigned int domid,
|
||||
struct domain *domain;
|
||||
int rc;
|
||||
|
||||
|
||||
domain = talloc(context, struct domain);
|
||||
domain->port = 0;
|
||||
domain->shutdown = 0;
|
||||
@@ -361,7 +362,7 @@ void do_introduce(struct connection *conn, struct buffered_data *in)
|
||||
/* 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)
|
||||
@@ -414,8 +415,6 @@ void do_release(struct connection *conn, const char *domid_str)
|
||||
|
||||
talloc_free(domain->conn);
|
||||
|
||||
fire_watches(conn, "@releaseDomain", false);
|
||||
|
||||
send_ack(conn, XS_RELEASE);
|
||||
}
|
||||
|
||||
|
||||