direct-io.hg
changeset 6701:47dca2f335de
Add simple transactional read/write python xenstore interface.
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author | cl349@firebug.cl.cam.ac.uk |
---|---|
date | Fri Sep 09 13:20:51 2005 +0000 (2005-09-09) |
parents | 4856f000d35d |
children | 3f4d14357976 d0b3c7061368 |
files | tools/python/xen/xend/xenstore/xstransact.py |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/tools/python/xen/xend/xenstore/xstransact.py Fri Sep 09 13:20:51 2005 +0000 1.3 @@ -0,0 +1,113 @@ 1.4 +# Copyright (C) 2005 Christian Limpach <Christian.Limpach@cl.cam.ac.uk> 1.5 + 1.6 +# This file is subject to the terms and conditions of the GNU General 1.7 +# Public License. See the file "COPYING" in the main directory of 1.8 +# this archive for more details. 1.9 + 1.10 +import threading 1.11 +from xen.lowlevel import xs 1.12 + 1.13 +handles = {} 1.14 + 1.15 +# XXX need to g/c handles from dead threads 1.16 +def xshandle(): 1.17 + if not handles.has_key(threading.currentThread()): 1.18 + handles[threading.currentThread()] = xs.open() 1.19 + return handles[threading.currentThread()] 1.20 + 1.21 +class xstransact: 1.22 + 1.23 + def __init__(self, path): 1.24 + self.path = path.rstrip("/") 1.25 + xshandle().transaction_start(path) 1.26 + self.in_transaction = True 1.27 + 1.28 + def __del__(self): 1.29 + if self.in_transaction: 1.30 + xshandle().transaction_end(True) 1.31 + 1.32 + def commit(self): 1.33 + if not self.in_transaction: 1.34 + raise RuntimeError 1.35 + self.in_transaction = False 1.36 + return xshandle().transaction_end(False) 1.37 + 1.38 + def abort(self): 1.39 + if not self.in_transaction: 1.40 + raise RuntimeError 1.41 + self.in_transaction = False 1.42 + return xshandle().transaction_end(True) 1.43 + 1.44 + def _read(self, key): 1.45 + path = "%s/%s" % (self.path, key) 1.46 + return xshandle().read(path) 1.47 + 1.48 + def read(self, *args): 1.49 + if len(args) == 0: 1.50 + raise TypeError 1.51 + if len(args) == 1: 1.52 + return self._read(args[0]) 1.53 + ret = [] 1.54 + for key in args: 1.55 + ret.append(self._read(key)) 1.56 + return ret 1.57 + 1.58 + def _write(self, key, data, create=True, excl=False): 1.59 + path = "%s/%s" % (self.path, key) 1.60 + xshandle().write(path, data, create=create, excl=excl) 1.61 + 1.62 + def write(self, *args, **opts): 1.63 + create = opts.get('create') or True 1.64 + excl = opts.get('excl') or False 1.65 + if len(args) == 0: 1.66 + raise TypeError 1.67 + if isinstance(args[0], dict): 1.68 + for d in args: 1.69 + if not isinstance(d, dict): 1.70 + raise TypeError 1.71 + for key in d.keys(): 1.72 + self._write(key, d[key], create, excl) 1.73 + elif isinstance(args[0], list): 1.74 + for l in args: 1.75 + if not len(l) == 2: 1.76 + raise TypeError 1.77 + self._write(l[0], l[1], create, excl) 1.78 + elif len(args) % 2 == 0: 1.79 + for i in range(len(args) / 2): 1.80 + self._write(args[i * 2], args[i * 2 + 1], create, excl) 1.81 + else: 1.82 + raise TypeError 1.83 + 1.84 + def Read(cls, path, *args): 1.85 + t = cls(path) 1.86 + v = t.read(*args) 1.87 + t.commit() 1.88 + return v 1.89 + 1.90 + Read = classmethod(Read) 1.91 + 1.92 + def Write(cls, path, *args, **opts): 1.93 + t = cls(path) 1.94 + t.write(*args, **opts) 1.95 + t.commit() 1.96 + 1.97 + Write = classmethod(Write) 1.98 + 1.99 + def SafeRead(cls, path, *args): 1.100 + while True: 1.101 + try: 1.102 + return cls.Read(path, *args) 1.103 + except RuntimeError, ex: 1.104 + pass 1.105 + 1.106 + SafeRead = classmethod(SafeRead) 1.107 + 1.108 + def SafeWrite(cls, path, *args, **opts): 1.109 + while True: 1.110 + try: 1.111 + cls.Write(path, *args, **opts) 1.112 + return 1.113 + except RuntimeError, ex: 1.114 + pass 1.115 + 1.116 + SafeWrite = classmethod(SafeWrite)