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

Re: [Xen-devel] [PATCH] libxenstore: fix threading bug which cause xend

To: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
Subject: Re: [Xen-devel] [PATCH] libxenstore: fix threading bug which cause xend startup hang
From: Ian Campbell <Ian.Campbell@xxxxxxxxxx>
Date: Fri, 10 Sep 2010 18:36:47 +0100
Cc: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Delivery-date: Fri, 10 Sep 2010 10:37:41 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <19594.25262.241563.656571@xxxxxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Organization: Citrix Systems, Inc.
References: <19594.25262.241563.656571@xxxxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Nice catch!

On Fri, 2010-09-10 at 17:54 +0100, Ian Jackson wrote: 
> @@ -662,21 +676,27 @@ char **xs_read_watch(struct xs_handle *h
>       struct xs_stored_msg *msg;
>       char **ret, *strings, c = 0;
>       unsigned int num_strings, i;
> -     int read_from_thread;
> -
> -     read_from_thread = read_thread_exists(h);
> -
> -     /* Read from comms channel ourselves if there is no reader thread. */
> -     if (!read_from_thread && (read_message(h) == -1))
> -             return NULL;
>  
>       mutex_lock(&h->watch_mutex);
>  
> -     /* Wait on the condition variable for a watch to fire. */
>  #ifdef USE_PTHREAD
> -     while (list_empty(&h->watch_list) && read_from_thread && h->fd != -1)
> +     /* Wait on the condition variable for a watch to fire.
> +      * If the reader thread doesn't exist yet, then that's because
> +      * we haven't called xs_watch.  Presumably the application
> +      * will do so later; in the meantime we just block.
> +      */
> +     while (list_empty(&h->watch_list) && h->fd != -1)
>               condvar_wait(&h->watch_condvar, &h->watch_mutex);
> -#endif
> +#else /* !defined(USE_PTHREAD) */
> +     /* Read from comms channel ourselves if there are no threads
> +      * and therefore no reader thread. */
> +
> +     assert(!read_thread_exists(h)); /* not threadsafe but worth a check */
> +     if ((read_message(h) == -1))
> +             return NULL;
> +
> +#endif /* !defined(USE_PTHREAD) */
> +
>       if (list_empty(&h->watch_list)) {
>               mutex_unlock(&h->watch_mutex);
>               errno = EINVAL;

read_reply contains a very similar pattern to the above. I assume it is
safe on that occasion because xs_talkv (the only caller of read_reply)
holds request_mutex?

If so then:
Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>

> @@ -900,6 +920,10 @@ char *xs_debug_command(struct xs_handle 
>  
>  static int read_message(struct xs_handle *h)
>  {
> +     /* IMPORTANT: It is forbidden to call this function without
> +      * acquiring the request lock and checking that h->read_thr_exists
> +      * is false.  See "Lock discipline" in struct xs_handle, above. */
> +         

Took me ages to figure realise this didn't apply ifndef USE_PTHREAD,
which is pretty obvious. Time to call it a day I think.

Ian.



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