direct-io.hg

changeset 7814:a064c5804eae

Fix race between xspy_read_watch and xspy_watch, by placing the watch in the
xshandle's list of watches *before* registering the watch with Xend.

Closes bug #392.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@leeni.uk.xensource.com
date Tue Nov 15 17:22:04 2005 +0100 (2005-11-15)
parents bb0e5f7f94fd
children 49bf2a4863b6
files tools/python/xen/lowlevel/xs/xs.c
line diff
     1.1 --- a/tools/python/xen/lowlevel/xs/xs.c	Tue Nov 15 16:24:31 2005 +0100
     1.2 +++ b/tools/python/xen/lowlevel/xs/xs.c	Tue Nov 15 17:22:04 2005 +0100
     1.3 @@ -16,7 +16,7 @@
     1.4   *
     1.5   * Copyright (C) 2005 Mike Wray Hewlett-Packard
     1.6   * Copyright (C) 2005 Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
     1.7 - *
     1.8 + * Copyright (C) 2005 XenSource Ltd.
     1.9   */
    1.10  
    1.11  #include <Python.h>
    1.12 @@ -453,25 +453,20 @@ static PyObject *xspy_watch(PyObject *se
    1.13  
    1.14      XsHandle *xsh = (XsHandle *)self;
    1.15      struct xs_handle *xh = xshandle(self);
    1.16 -    PyObject *val = NULL;
    1.17      int xsval = 0;
    1.18  
    1.19      if (!xh)
    1.20 -        goto exit;
    1.21 +        return NULL;
    1.22      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, 
    1.23                                       &path, &token))
    1.24 -        goto exit;
    1.25 +        return NULL;
    1.26 +
    1.27 +    /* Note that we have to store the watch token in the xs->watches list
    1.28 +       before registering the watch with xs_watch, otherwise this function
    1.29 +       races with xs_read_watch.
    1.30 +    */
    1.31 +
    1.32      Py_INCREF(token);
    1.33 -    sprintf(token_str, "%li", (unsigned long)token);
    1.34 -    Py_BEGIN_ALLOW_THREADS
    1.35 -    xsval = xs_watch(xh, path, token_str);
    1.36 -    Py_END_ALLOW_THREADS
    1.37 -    if (!xsval) {
    1.38 -        PyErr_SetFromErrno(PyExc_RuntimeError);
    1.39 -        Py_DECREF(token);
    1.40 -        goto exit;
    1.41 -    }
    1.42 -
    1.43      for (i = 0; i < PyList_Size(xsh->watches); i++) {
    1.44          if (PyList_GetItem(xsh->watches, i) == Py_None) {
    1.45              PyList_SetItem(xsh->watches, i, token);
    1.46 @@ -480,10 +475,26 @@ static PyObject *xspy_watch(PyObject *se
    1.47      }
    1.48      if (i == PyList_Size(xsh->watches))
    1.49          PyList_Append(xsh->watches, token);
    1.50 +
    1.51 +    sprintf(token_str, "%li", (unsigned long)token);
    1.52 +    Py_BEGIN_ALLOW_THREADS
    1.53 +    xsval = xs_watch(xh, path, token_str);
    1.54 +    Py_END_ALLOW_THREADS
    1.55 +    if (!xsval) {
    1.56 +        for (i = 0; i < PyList_Size(xsh->watches); i++) {
    1.57 +            if (PyList_GetItem(xsh->watches, i) == token) {
    1.58 +                Py_INCREF(Py_None);
    1.59 +                PyList_SetItem(xsh->watches, i,  Py_None);
    1.60 +                break;
    1.61 +            }
    1.62 +        }
    1.63 +
    1.64 +        PyErr_SetFromErrno(PyExc_RuntimeError);
    1.65 +        return NULL;
    1.66 +    }
    1.67 +
    1.68      Py_INCREF(Py_None);
    1.69 -    val = Py_None;
    1.70 - exit:
    1.71 -    return val;
    1.72 +    return Py_None;
    1.73  }
    1.74  
    1.75  #define xspy_read_watch_doc "\n"				\
    1.76 @@ -944,3 +955,11 @@ PyMODINIT_FUNC initxs (void)
    1.77  
    1.78      module = Py_InitModule(PYPKG, xs_methods);
    1.79  }
    1.80 +
    1.81 +
    1.82 +/*
    1.83 + * Local variables:
    1.84 + *  c-indent-level: 4
    1.85 + *  c-basic-offset: 4
    1.86 + * End:
    1.87 + */