Message ID | 1506012428-59769-3-git-send-email-euan.harris@citrix.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thu, Sep 21, 2017 at 05:47:07PM +0100, Euan Harris wrote: > When a watch fires, xspy_read_watch() checks whether the client has > registered interest in the path which changed and, if so, returns the > path and a client-supplied token. The binding for xs_check_watch() > needs to do the same, so this patch extracts the search code into a > separate function. > > Signed-off-by: Euan Harris <euan.harris@citrix.com> > Reviewed-by: Wei Liu <wei.liu2@citrix.com> Acked-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com> > --- > Changed since v1: > * Remove stray newline > * Fix indentation > > tools/python/xen/lowlevel/xs/xs.c | 60 ++++++++++++++++++++++++--------------- > 1 file changed, 37 insertions(+), 23 deletions(-) > > diff --git a/tools/python/xen/lowlevel/xs/xs.c b/tools/python/xen/lowlevel/xs/xs.c > index 9f1b916..2af5e07 100644 > --- a/tools/python/xen/lowlevel/xs/xs.c > +++ b/tools/python/xen/lowlevel/xs/xs.c > @@ -77,6 +77,8 @@ static inline struct xs_handle *xshandle(XsHandle *self) > > static void remove_watch(XsHandle *xsh, PyObject *token); > > +static PyObject *match_watch_by_token(XsHandle *self, char **xsval); > + > static PyObject *none(bool result); > > static int parse_transaction_path(XsHandle *self, PyObject *args, > @@ -484,8 +486,6 @@ static PyObject *xspy_read_watch(XsHandle *self, PyObject *args) > struct xs_handle *xh = xshandle(self); > PyObject *val = NULL; > char **xsval; > - PyObject *token; > - int i; > unsigned int num; > > if (!xh) > @@ -497,29 +497,16 @@ again: > Py_END_ALLOW_THREADS > if (!xsval) { > PyErr_SetFromErrno(xs_error); > - goto exit; > - } > - if (sscanf(xsval[XS_WATCH_TOKEN], "%li", (unsigned long *)&token) != 1) { > - xs_set_error(EINVAL); > - goto exit; > - } > - for (i = 0; i < PyList_Size(self->watches); i++) { > - if (token == PyList_GetItem(self->watches, i)) > - break; > - } > - if (i == PyList_Size(self->watches)) { > - /* We do not have a registered watch for the one that has just fired. > - Ignore this -- a watch that has been recently deregistered can still > - have watches in transit. This is a blocking method, so go back to > - read again. > - */ > - free(xsval); > - goto again; > + return val; > } > - /* Create tuple (path, token). */ > - val = Py_BuildValue("(sO)", xsval[XS_WATCH_PATH], token); > - exit: > + > + val = match_watch_by_token(self, xsval); > free(xsval); > + > + if (!val && errno == EAGAIN) { > + goto again; > + } > + > return val; > } > > @@ -868,6 +855,33 @@ static int parse_transaction_path(XsHandle *self, PyObject *args, > } > > > +static PyObject *match_watch_by_token(XsHandle *self, char **xsval) > +{ > + PyObject *token; > + int i; > + > + if (sscanf(xsval[XS_WATCH_TOKEN], "%li", (unsigned long *)&token) != 1) { > + xs_set_error(EINVAL); > + return NULL; > + } > + for (i = 0; i < PyList_Size(self->watches); i++) { > + if (token == PyList_GetItem(self->watches, i)) > + break; > + } > + if (i == PyList_Size(self->watches)) { > + /* We do not have a registered watch for the one that has just fired. > + Ignore this -- a watch that has been recently deregistered can still > + have watches in transit. > + */ > + xs_set_error(EAGAIN); > + return NULL; > + } > + > + /* Create tuple (path, token). */ > + return Py_BuildValue("(sO)", xsval[XS_WATCH_PATH], token); > +} > + > + > static PyObject *none(bool result) > { > if (result) {
diff --git a/tools/python/xen/lowlevel/xs/xs.c b/tools/python/xen/lowlevel/xs/xs.c index 9f1b916..2af5e07 100644 --- a/tools/python/xen/lowlevel/xs/xs.c +++ b/tools/python/xen/lowlevel/xs/xs.c @@ -77,6 +77,8 @@ static inline struct xs_handle *xshandle(XsHandle *self) static void remove_watch(XsHandle *xsh, PyObject *token); +static PyObject *match_watch_by_token(XsHandle *self, char **xsval); + static PyObject *none(bool result); static int parse_transaction_path(XsHandle *self, PyObject *args, @@ -484,8 +486,6 @@ static PyObject *xspy_read_watch(XsHandle *self, PyObject *args) struct xs_handle *xh = xshandle(self); PyObject *val = NULL; char **xsval; - PyObject *token; - int i; unsigned int num; if (!xh) @@ -497,29 +497,16 @@ again: Py_END_ALLOW_THREADS if (!xsval) { PyErr_SetFromErrno(xs_error); - goto exit; - } - if (sscanf(xsval[XS_WATCH_TOKEN], "%li", (unsigned long *)&token) != 1) { - xs_set_error(EINVAL); - goto exit; - } - for (i = 0; i < PyList_Size(self->watches); i++) { - if (token == PyList_GetItem(self->watches, i)) - break; - } - if (i == PyList_Size(self->watches)) { - /* We do not have a registered watch for the one that has just fired. - Ignore this -- a watch that has been recently deregistered can still - have watches in transit. This is a blocking method, so go back to - read again. - */ - free(xsval); - goto again; + return val; } - /* Create tuple (path, token). */ - val = Py_BuildValue("(sO)", xsval[XS_WATCH_PATH], token); - exit: + + val = match_watch_by_token(self, xsval); free(xsval); + + if (!val && errno == EAGAIN) { + goto again; + } + return val; } @@ -868,6 +855,33 @@ static int parse_transaction_path(XsHandle *self, PyObject *args, } +static PyObject *match_watch_by_token(XsHandle *self, char **xsval) +{ + PyObject *token; + int i; + + if (sscanf(xsval[XS_WATCH_TOKEN], "%li", (unsigned long *)&token) != 1) { + xs_set_error(EINVAL); + return NULL; + } + for (i = 0; i < PyList_Size(self->watches); i++) { + if (token == PyList_GetItem(self->watches, i)) + break; + } + if (i == PyList_Size(self->watches)) { + /* We do not have a registered watch for the one that has just fired. + Ignore this -- a watch that has been recently deregistered can still + have watches in transit. + */ + xs_set_error(EAGAIN); + return NULL; + } + + /* Create tuple (path, token). */ + return Py_BuildValue("(sO)", xsval[XS_WATCH_PATH], token); +} + + static PyObject *none(bool result) { if (result) {