~ubuntu-branches/ubuntu/utopic/xen/utopic

« back to all changes in this revision

Viewing changes to tools/python/xen/xend/xenstore/xswatch.py

  • Committer: Bazaar Package Importer
  • Author(s): Bastian Blank
  • Date: 2010-05-06 15:47:38 UTC
  • mto: (1.3.1) (15.1.1 sid) (4.1.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20100506154738-agoz0rlafrh1fnq7
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005 Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
 
2
# Copyright (C) 2005 XenSource Ltd
 
3
 
 
4
# This file is subject to the terms and conditions of the GNU General
 
5
# Public License.  See the file "COPYING" in the main directory of
 
6
# this archive for more details.
 
7
 
 
8
import errno
 
9
import threading
 
10
from xen.xend.xenstore.xsutil import xshandle
 
11
 
 
12
 
 
13
class xswatch:
 
14
 
 
15
    ##
 
16
    # Create a watch on the given path in the store.  The watch will fire
 
17
    # immediately, then subsequently each time the watched path is changed,
 
18
    # until the watch is deregistered, either by the return value from the
 
19
    # watch callback being False, or by an explicit call to unwatch.
 
20
    #
 
21
    # @param fn The function to be called when the watch fires.  This function
 
22
    # should take the path that has changed as its first argument, followed by
 
23
    # the extra arguments given to this constructor, if any.  It should return
 
24
    # True if the watch is to remain registered, or False if it is to be
 
25
    # deregistered.
 
26
    #
 
27
    def __init__(self, path, fn, *args, **kwargs):
 
28
        self.path = path
 
29
        self.fn = fn
 
30
        self.args = args
 
31
        self.kwargs = kwargs
 
32
        watchStart()
 
33
        xs.watch(path, self)
 
34
 
 
35
 
 
36
    def unwatch(self):
 
37
        xs.unwatch(self.path, self)
 
38
 
 
39
 
 
40
watchThread = None
 
41
xs = None
 
42
xslock = threading.Lock()
 
43
 
 
44
def watchStart():
 
45
    global watchThread
 
46
    global xs
 
47
    
 
48
    xslock.acquire()
 
49
    try:
 
50
        if watchThread:
 
51
            return
 
52
        xs = xshandle()
 
53
        watchThread = threading.Thread(name="Watcher", target=watchMain)
 
54
        watchThread.setDaemon(True)
 
55
        watchThread.start()
 
56
    finally:
 
57
        xslock.release()
 
58
 
 
59
 
 
60
def watchMain():
 
61
    while True:
 
62
        try:
 
63
            we = xs.read_watch()
 
64
            watch = we[1]
 
65
            res = watch.fn(we[0], *watch.args, **watch.kwargs)
 
66
            if not res:
 
67
                try:
 
68
                    watch.unwatch()
 
69
                except RuntimeError, exn:
 
70
                    if exn.args[0] == errno.ENOENT:
 
71
                        # The watch has already been unregistered -- that's
 
72
                        # fine.
 
73
                        pass
 
74
                    else:
 
75
                        raise
 
76
        except:
 
77
            pass
 
78
            # Ignore this exception -- there's no point throwing it
 
79
            # further on because that will just kill the watcher thread,
 
80
            # which achieves nothing.