[project @ 2006-05-07 18:36:40 by warner]
[buildbot.git] / buildbot / locks.py
bloba5ae40b933db3c6b3054f7ada3599fd1290d7988
1 # -*- test-case-name: buildbot.test.test_locks -*-
3 from twisted.python import log
4 from twisted.internet import reactor, defer
5 from buildbot import util
7 class BaseLock:
8 owner = None
9 description = "<BaseLock>"
11 def __init__(self, name):
12 self.name = name
13 self.waiting = []
15 def __repr__(self):
16 return self.description
18 def isAvailable(self):
19 log.msg("%s isAvailable: self.owner=%s" % (self, self.owner))
20 return not self.owner
22 def claim(self, owner):
23 log.msg("%s claim(%s)" % (self, owner))
24 assert owner is not None
25 self.owner = owner
26 log.msg(" %s is claimed" % (self,))
28 def release(self, owner):
29 log.msg("%s release(%s)" % (self, owner))
30 assert owner is self.owner
31 self.owner = None
32 reactor.callLater(0, self.nowAvailable)
34 def waitUntilAvailable(self, owner):
35 log.msg("%s waitUntilAvailable(%s)" % (self, owner))
36 assert self.owner, "You aren't supposed to call this on a free Lock"
37 d = defer.Deferred()
38 self.waiting.append((d, owner))
39 return d
41 def nowAvailable(self):
42 log.msg("%s nowAvailable" % self)
43 assert not self.owner
44 if not self.waiting:
45 return
46 d,owner = self.waiting.pop(0)
47 d.callback(self)
49 class RealMasterLock(BaseLock):
50 def __init__(self, name):
51 BaseLock.__init__(self, name)
52 self.description = "<MasterLock(%s)>" % (name,)
54 def getLock(self, slave):
55 return self
57 class RealSlaveLock(BaseLock):
58 def __init__(self, name):
59 BaseLock.__init__(self, name)
60 self.description = "<SlaveLock(%s)>" % (name,)
61 self.locks = {}
63 def getLock(self, slavebuilder):
64 slavename = slavebuilder.slave.slavename
65 if not self.locks.has_key(slavename):
66 lock = self.locks[slavename] = BaseLock(self.name)
67 lock.description = "<SlaveLock(%s)[%s] %d>" % (self.name,
68 slavename,
69 id(lock))
70 self.locks[slavename] = lock
71 return self.locks[slavename]
74 # master.cfg should only reference the following MasterLock and SlaveLock
75 # classes. They are identifiers that will be turned into real Locks later,
76 # via the BotMaster.getLockByID method.
78 class MasterLock(util.ComparableMixin):
79 compare_attrs = ['name']
80 lockClass = RealMasterLock
81 def __init__(self, name):
82 self.name = name
84 class SlaveLock(util.ComparableMixin):
85 compare_attrs = ['name']
86 lockClass = RealSlaveLock
87 def __init__(self, name):
88 self.name = name