From: Jeremy Fitzhardinge <jeremy@goop.org>
To: Keir Fraser <keir.fraser@eu.citrix.com>
Cc: Xen-devel <xen-devel@lists.xensource.com>,
Stefano Stabellini <Stefano.Stabellini@eu.citrix.com>
Subject: [PATCH 1 of 2] xs: make sure mutexes are cleaned up and memory freed if the read thread is cancelled
Date: Tue, 11 May 2010 15:02:54 -0700 [thread overview]
Message-ID: <4BE9D40E.4010700@goop.org> (raw)
In-Reply-To: <4BE9D3B9.2050206@goop.org>
If the read thread is terminated with pthread cancel, it must make sure
all memory is freed and mutexes are unlocked.
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
diff -r d77a88f938c6 tools/xenstore/xs.c
--- a/tools/xenstore/xs.c Tue May 11 14:05:28 2010 +0100
+++ b/tools/xenstore/xs.c Tue May 11 14:55:14 2010 -0700
@@ -85,6 +85,8 @@
#define mutex_unlock(m) pthread_mutex_unlock(m)
#define condvar_signal(c) pthread_cond_signal(c)
#define condvar_wait(c,m,hnd) pthread_cond_wait(c,m)
+#define cleanup_push(f, a) pthread_cleanup_push((void (*)(void *))(f), (void *)(a))
+#define cleanup_pop(run) pthread_cleanup_pop(run)
static void *read_thread(void *arg);
@@ -102,6 +104,8 @@
#define mutex_unlock(m) ((void)0)
#define condvar_signal(c) ((void)0)
#define condvar_wait(c,m,hnd) read_message(hnd)
+#define cleanup_push(f, a) ((void)0)
+#define cleanup_pop(run) ((void)0)
#endif
@@ -262,7 +266,6 @@
#ifdef USE_PTHREAD
if (h->read_thr_exists) {
- /* XXX FIXME: May leak an unpublished message buffer. */
pthread_cancel(h->read_thr);
pthread_join(h->read_thr, NULL);
}
@@ -860,44 +863,53 @@
{
struct xs_stored_msg *msg = NULL;
char *body = NULL;
- int saved_errno;
+ int saved_errno = 0;
+ int ret = -1;
/* Allocate message structure and read the message header. */
msg = malloc(sizeof(*msg));
if (msg == NULL)
goto error;
- if (!read_all(h->fd, &msg->hdr, sizeof(msg->hdr)))
- goto error;
+ cleanup_push(free, msg);
+ if (!read_all(h->fd, &msg->hdr, sizeof(msg->hdr))) { /* Cancellation point */
+ saved_errno = errno;
+ goto error_freemsg;
+ }
/* Allocate and read the message body. */
body = msg->body = malloc(msg->hdr.len + 1);
if (body == NULL)
- goto error;
- if (!read_all(h->fd, body, msg->hdr.len))
- goto error;
+ goto error_freemsg;
+ cleanup_push(free, body);
+ if (!read_all(h->fd, body, msg->hdr.len)) { /* Cancellation point */
+ saved_errno = errno;
+ goto error_freebody;
+ }
+
body[msg->hdr.len] = '\0';
if (msg->hdr.type == XS_WATCH_EVENT) {
mutex_lock(&h->watch_mutex);
+ cleanup_push(pthread_mutex_unlock, &h->watch_mutex);
/* Kick users out of their select() loop. */
if (list_empty(&h->watch_list) &&
(h->watch_pipe[1] != -1))
- while (write(h->watch_pipe[1], body, 1) != 1)
+ while (write(h->watch_pipe[1], body, 1) != 1) /* Cancellation point */
continue;
list_add_tail(&msg->list, &h->watch_list);
condvar_signal(&h->watch_condvar);
- mutex_unlock(&h->watch_mutex);
+ cleanup_pop(1);
} else {
mutex_lock(&h->reply_mutex);
/* There should only ever be one response pending! */
if (!list_empty(&h->reply_list)) {
mutex_unlock(&h->reply_mutex);
- goto error;
+ goto error_freebody;
}
list_add_tail(&msg->list, &h->reply_list);
@@ -906,14 +918,16 @@
mutex_unlock(&h->reply_mutex);
}
- return 0;
+ ret = 0;
- error:
- saved_errno = errno;
- free(msg);
- free(body);
+error_freebody:
+ cleanup_pop(ret == -1);
+error_freemsg:
+ cleanup_pop(ret == -1);
+error:
errno = saved_errno;
- return -1;
+
+ return ret;
}
#ifdef USE_PTHREAD
next prev parent reply other threads:[~2010-05-11 22:02 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-11 22:01 Shutdown problems in xs.c Jeremy Fitzhardinge
2010-05-11 22:02 ` Jeremy Fitzhardinge [this message]
2010-05-11 22:03 ` [PATCH 2 of 2] xs: avoid pthread_join deadlock in xs_daemon_close Jeremy Fitzhardinge
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=4BE9D40E.4010700@goop.org \
--to=jeremy@goop.org \
--cc=Stefano.Stabellini@eu.citrix.com \
--cc=keir.fraser@eu.citrix.com \
--cc=xen-devel@lists.xensource.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.