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

[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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Add python bindings for watches., Xen patchbot -unstable <=