[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Add python bindings for watches.
# HG changeset patch # User cl349@xxxxxxxxxxxxxxxxxxxx # Node ID 63e226a5e272b4d99461a39e188a20431e10f898 # Parent 99f12399b25a969989af0543da0330601f562f65 Add python bindings for watches. Uses a watcher thread with per-watch registered callbacks. Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx> diff -r 99f12399b25a -r 63e226a5e272 tools/python/xen/lowlevel/xs/xs.c --- a/tools/python/xen/lowlevel/xs/xs.c Wed Sep 7 01:03:02 2005 +++ b/tools/python/xen/lowlevel/xs/xs.c Wed Sep 7 12:47:45 2005 @@ -45,6 +45,7 @@ typedef struct XsHandle { PyObject_HEAD; struct xs_handle *xh; + PyObject *watches; } XsHandle; static inline struct xs_handle *xshandle(PyObject *self) @@ -355,13 +356,19 @@ "Raises RuntimeError on error.\n" \ "\n" +/* Each 10 bits takes ~ 3 digits, plus one, plus one for nul terminator. */ +#define MAX_STRLEN(x) ((sizeof(x) * CHAR_BIT + CHAR_BIT-1) / 10 * 3 + 2) + static PyObject *xspy_watch(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwd_spec[] = { "path", "token", NULL }; - static char *arg_spec = "s|is"; - char *path = NULL; - char *token = ""; - + static char *arg_spec = "sO"; + char *path = NULL; + PyObject *token; + char token_str[MAX_STRLEN(unsigned long) + 1]; + int i; + + XsHandle *xsh = (XsHandle *)self; struct xs_handle *xh = xshandle(self); PyObject *val = NULL; int xsval = 0; @@ -371,8 +378,21 @@ if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path, &token)) goto exit; - xsval = xs_watch(xh, path, token); - val = pyvalue_int(xsval); + Py_INCREF(token); + sprintf(token_str, "%li", (unsigned long)token); + xsval = xs_watch(xh, path, token_str); + val = pyvalue_int(xsval); + if (xsval) { + for (i = 0; i < PyList_Size(xsh->watches); i++) { + if (PyList_GetItem(xsh->watches, i) == Py_None) { + PyList_SetItem(xsh->watches, i, token); + break; + } + } + if (i == PyList_Size(xsh->watches)) + PyList_Append(xsh->watches, token); + } else + Py_DECREF(token); exit: return val; } @@ -393,9 +413,12 @@ static char *kwd_spec[] = { NULL }; static char *arg_spec = ""; + XsHandle *xsh = (XsHandle *)self; struct xs_handle *xh = xshandle(self); PyObject *val = NULL; char **xsval = NULL; + PyObject *token; + int i; if (!xh) goto exit; @@ -403,11 +426,23 @@ goto exit; xsval = xs_read_watch(xh); if (!xsval) { - val = PyErr_SetFromErrno(PyExc_RuntimeError); - goto exit; + val = PyErr_SetFromErrno(PyExc_RuntimeError); + goto exit; + } + if (sscanf(xsval[1], "%li", (unsigned long *)&token) != 1) { + PyErr_SetString(PyExc_RuntimeError, "invalid token"); + goto exit; + } + for (i = 0; i < PyList_Size(xsh->watches); i++) { + if (token == PyList_GetItem(xsh->watches, i)) + break; + } + if (i == PyList_Size(xsh->watches)) { + PyErr_SetString(PyExc_RuntimeError, "invalid token"); + goto exit; } /* Create tuple (path, token). */ - val = Py_BuildValue("(ss)", xsval[0], xsval[1]); + val = Py_BuildValue("(sO)", xsval[0], token); exit: if (xsval) free(xsval); @@ -426,8 +461,9 @@ PyObject *kwds) { static char *kwd_spec[] = { "token", NULL }; - static char *arg_spec = "s"; - char *token; + static char *arg_spec = "O"; + PyObject *token; + char token_str[MAX_STRLEN(unsigned long) + 1]; struct xs_handle *xh = xshandle(self); PyObject *val = NULL; @@ -437,7 +473,8 @@ goto exit; if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &token)) goto exit; - xsval = xs_acknowledge_watch(xh, token); + sprintf(token_str, "%li", (unsigned long)token); + xsval = xs_acknowledge_watch(xh, token_str); val = pyvalue_int(xsval); exit: return val; @@ -455,10 +492,13 @@ static PyObject *xspy_unwatch(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwd_spec[] = { "path", "token", NULL }; - static char *arg_spec = "s|s"; - char *path = NULL; - char *token = ""; - + static char *arg_spec = "sO"; + char *path = NULL; + PyObject *token; + char token_str[MAX_STRLEN(unsigned long) + 1]; + int i; + + XsHandle *xsh = (XsHandle *)self; struct xs_handle *xh = xshandle(self); PyObject *val = NULL; int xsval = 0; @@ -468,8 +508,16 @@ if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path, &token)) goto exit; - xsval = xs_unwatch(xh, path, token); - val = pyvalue_int(xsval); + sprintf(token_str, "%li", (unsigned long)token); + xsval = xs_unwatch(xh, path, token_str); + val = pyvalue_int(xsval); + for (i = 0; i < PyList_Size(xsh->watches); i++) { + if (token == PyList_GetItem(xsh->watches, i)) { + Py_INCREF(Py_None); + PyList_SetItem(xsh->watches, i, Py_None); + break; + } + } exit: return val; } @@ -612,7 +660,9 @@ { static char *kwd_spec[] = { NULL }; static char *arg_spec = ""; - + int i; + + XsHandle *xsh = (XsHandle *)self; struct xs_handle *xh = xshandle(self); PyObject *val = NULL; int xsval = 1; @@ -621,8 +671,13 @@ goto exit; if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec)) goto exit; + for (i = 0; i < PyList_Size(xsh->watches); i++) { + /* TODO: xs_unwatch watches */ + Py_INCREF(Py_None); + PyList_SetItem(xsh->watches, i, Py_None); + } xs_daemon_close(xh); - ((XsHandle*)self)->xh = NULL; + xsh->xh = NULL; val = pyvalue_int(xsval); exit: return val; @@ -750,20 +805,24 @@ if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &readonly)) - goto exit; + return NULL; xsh = PyObject_New(XsHandle, &xshandle_type); if (!xsh) + return NULL; + xsh->watches = PyList_New(0); + if (!xsh->watches) goto exit; xsh->xh = (readonly ? xs_daemon_open_readonly() : xs_daemon_open()); if (!xsh->xh) { - PyObject_Del(xsh); - val = pyvalue_int(0); + Py_DECREF(xsh->watches); goto exit; } val = (PyObject *)xsh; - exit: - return val; + return val; + exit: + PyObject_Del(xsh); + return NULL; } static PyMethodDef xs_methods[] = { diff -r 99f12399b25a -r 63e226a5e272 tools/python/xen/xend/xenstore/xswatch.py --- /dev/null Wed Sep 7 01:03:02 2005 +++ b/tools/python/xen/xend/xenstore/xswatch.py Wed Sep 7 12:47:45 2005 @@ -0,0 +1,62 @@ + +import select +import threading +from xen.lowlevel import xs + +class xswatch: + + watchThread = None + threadcond = threading.Condition() + xs = None + xslock = threading.Lock() + watches = [] + + def __init__(self, path, fn, args=(), kwargs={}): + self.fn = fn + self.args = args + self.kwargs = kwargs + xswatch.watchStart() + xswatch.xslock.acquire() + xswatch.xs.watch(path, self) + xswatch.xslock.release() + xswatch.watches.append(self) + + def watchStart(cls): + cls.threadcond.acquire() + if cls.watchThread: + cls.threadcond.release() + return + cls.watchThread = threading.Thread(name="Watcher", + target=cls.watchMain) + cls.watchThread.setDaemon(True) + cls.watchThread.start() + while cls.xs == None: + cls.threadcond.wait() + cls.threadcond.release() + + watchStart = classmethod(watchStart) + + def watchMain(cls): + cls.threadcond.acquire() + cls.xs = xs.open() + cls.threadcond.notifyAll() + cls.threadcond.release() + while True: + try: + (ord, owr, oer) = select.select([ cls.xs ], [], []) + cls.xslock.acquire() + # reconfirm ready to read with lock + (ord, owr, oer) = select.select([ cls.xs ], [], [], 0.001) + if not cls.xs in ord: + cls.xslock.release() + continue + we = cls.xs.read_watch() + watch = we[1] + cls.xs.acknowledge_watch(watch) + cls.xslock.release() + except RuntimeError, ex: + print ex + raise + watch.fn(*watch.args, **watch.kwargs) + + watchMain = classmethod(watchMain) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |