Make libxenstore thread-safe. It also spawns an internal

thread to read messages from the comms channel.

Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
kaf24@firebug.cl.cam.ac.uk committed 2005-10-08 19:19:27 +01:00
1 parent 47f583a947
commit 7429d6e032
14 files changed
+300 -306

No files matched your search

-57
View File
@@ -775,39 +775,6 @@ static PyObject *xspy_close(PyObject *self, PyObject *args, PyObject *kwds)
return val;
}
#define xspy_shutdown_doc "\n" \
"Shutdown the xenstore daemon.\n" \
"\n" \
"Returns None on success.\n" \
"Raises RuntimeError on error.\n" \
"\n"
static PyObject *xspy_shutdown(PyObject *self, PyObject *args, PyObject *kwds)
{
static char *kwd_spec[] = { NULL };
static char *arg_spec = "";
struct xs_handle *xh = xshandle(self);
PyObject *val = NULL;
int xsval = 0;
if (!xh)
goto exit;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec))
goto exit;
Py_BEGIN_ALLOW_THREADS
xsval = xs_shutdown(xh);
Py_END_ALLOW_THREADS
if (!xsval) {
PyErr_SetFromErrno(PyExc_RuntimeError);
goto exit;
}
Py_INCREF(Py_None);
val = Py_None;
exit:
return val;
}
#define xspy_get_domain_path_doc "\n" \
"Return store path of domain.\n" \
" domid [int]: domain id\n" \
@@ -850,28 +817,6 @@ static PyObject *xspy_get_domain_path(PyObject *self, PyObject *args,
return val;
}
#define xspy_fileno_doc "\n" \
"Get the file descriptor of the xenstore socket.\n" \
"Allows an xs object to be passed to select().\n" \
"\n" \
"Returns: [int] file descriptor.\n" \
"\n"
static PyObject *xspy_fileno(PyObject *self, PyObject *args, PyObject *kwds)
{
static char *kwd_spec[] = { NULL };
static char *arg_spec = "";
struct xs_handle *xh = xshandle(self);
PyObject *val = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec))
goto exit;
val = PyInt_FromLong((xh ? xs_fileno(xh) : -1));
exit:
return val;
}
#define XSPY_METH(_name) { \
.ml_name = #_name, \
.ml_meth = (PyCFunction) xspy_ ## _name, \
@@ -895,9 +840,7 @@ static PyMethodDef xshandle_methods[] = {
XSPY_METH(introduce_domain),
XSPY_METH(release_domain),
XSPY_METH(close),
XSPY_METH(shutdown),
XSPY_METH(get_domain_path),
XSPY_METH(fileno),
{ /* Terminator. */ },
};
+9 -6
View File
@@ -7,14 +7,17 @@
import threading
from xen.lowlevel import xs
handles = {}
xs_lock = threading.Lock()
xs_handle = None
# XXX need to g/c handles from dead threads
def xshandle():
if not handles.has_key(threading.currentThread()):
handles[threading.currentThread()] = xs.open()
return handles[threading.currentThread()]
global xs_handle, xs_lock
if not xs_handle:
xs_lock.acquire()
if not xs_handle:
xs_handle = xs.open()
xs_lock.release()
return xs_handle
def IntroduceDomain(domid, page, port, path):
return xshandle().introduce_domain(domid, page, port, path)
+7 -20
View File
@@ -12,7 +12,6 @@ from xen.lowlevel import xs
class xswatch:
watchThread = None
threadcond = threading.Condition()
xs = None
xslock = threading.Lock()
@@ -21,43 +20,31 @@ class xswatch:
self.args = args
self.kwargs = kwargs
xswatch.watchStart()
xswatch.xslock.acquire()
xswatch.xs.watch(path, self)
xswatch.xslock.release()
def watchStart(cls):
cls.threadcond.acquire()
cls.xslock.acquire()
if cls.watchThread:
cls.threadcond.release()
cls.xslock.release()
return
# XXX: When we fix xenstored to have better watch semantics,
# this can change to shared xshandle(). Currently that would result
# in duplicate watch firings, thus failed extra xs.acknowledge_watch.
cls.xs = xs.open()
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()
cls.xslock.release()
watchStart = classmethod(watchStart)
def watchMain(cls):
cls.threadcond.acquire()
cls.xs = xs.open()
cls.threadcond.notifyAll()
cls.threadcond.release()
while True:
try:
(fd, _1, _2) = select.select([ cls.xs ], [], [])
cls.xslock.acquire()
# reconfirm ready to read with lock
(fd, _1, _2) = select.select([ cls.xs ], [], [], 0.001)
if not cls.xs in fd:
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
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.