Index: third_party/buildbot_7_12/buildbot/locks.py |
diff --git a/third_party/buildbot_7_12/buildbot/locks.py b/third_party/buildbot_7_12/buildbot/locks.py |
deleted file mode 100644 |
index aa7b93d2f4be69f540fbd13b47fa6601ba557aae..0000000000000000000000000000000000000000 |
--- a/third_party/buildbot_7_12/buildbot/locks.py |
+++ /dev/null |
@@ -1,249 +0,0 @@ |
-# -*- test-case-name: buildbot.test.test_locks -*- |
- |
-from twisted.python import log |
-from twisted.internet import reactor, defer |
-from buildbot import util |
- |
-if False: # for debugging |
- debuglog = log.msg |
-else: |
- debuglog = lambda m: None |
- |
-class BaseLock: |
- """ |
- Class handling claiming and releasing of L{self}, and keeping track of |
- current and waiting owners. |
- |
- @note: Ideally, we'd like to maintain FIFO order. The place to do that |
- would be the L{isAvailable()} function. However, this function is |
- called by builds/steps both for the first time, and after waking |
- them up by L{self} from the L{self.waiting} queue. There is |
- currently no way of distinguishing between them. |
- """ |
- description = "<BaseLock>" |
- |
- def __init__(self, name, maxCount=1): |
- self.name = name # Name of the lock |
- self.waiting = [] # Current queue, tuples (LockAccess, deferred) |
- self.owners = [] # Current owners, tuples (owner, LockAccess) |
- self.maxCount=maxCount # maximal number of counting owners |
- |
- def __repr__(self): |
- return self.description |
- |
- def _getOwnersCount(self): |
- """ Return the number of current exclusive and counting owners. |
- |
- @return: Tuple (number exclusive owners, number counting owners) |
- """ |
- num_excl, num_counting = 0, 0 |
- for owner in self.owners: |
- if owner[1].mode == 'exclusive': |
- num_excl = num_excl + 1 |
- else: # mode == 'counting' |
- num_counting = num_counting + 1 |
- |
- assert (num_excl == 1 and num_counting == 0) \ |
- or (num_excl == 0 and num_counting <= self.maxCount) |
- return num_excl, num_counting |
- |
- |
- def isAvailable(self, access): |
- """ Return a boolean whether the lock is available for claiming """ |
- debuglog("%s isAvailable(%s): self.owners=%r" |
- % (self, access, self.owners)) |
- num_excl, num_counting = self._getOwnersCount() |
- if access.mode == 'counting': |
- # Wants counting access |
- return num_excl == 0 and num_counting < self.maxCount |
- else: |
- # Wants exclusive access |
- return num_excl == 0 and num_counting == 0 |
- |
- def claim(self, owner, access): |
- """ Claim the lock (lock must be available) """ |
- debuglog("%s claim(%s, %s)" % (self, owner, access.mode)) |
- assert owner is not None |
- assert self.isAvailable(access), "ask for isAvailable() first" |
- |
- assert isinstance(access, LockAccess) |
- assert access.mode in ['counting', 'exclusive'] |
- self.owners.append((owner, access)) |
- debuglog(" %s is claimed '%s'" % (self, access.mode)) |
- |
- def release(self, owner, access): |
- """ Release the lock """ |
- assert isinstance(access, LockAccess) |
- |
- debuglog("%s release(%s, %s)" % (self, owner, access.mode)) |
- entry = (owner, access) |
- assert entry in self.owners |
- self.owners.remove(entry) |
- # who can we wake up? |
- # After an exclusive access, we may need to wake up several waiting. |
- # Break out of the loop when the first waiting client should not be awakened. |
- num_excl, num_counting = self._getOwnersCount() |
- while len(self.waiting) > 0: |
- access, d = self.waiting[0] |
- if access.mode == 'counting': |
- if num_excl > 0 or num_counting == self.maxCount: |
- break |
- else: |
- num_counting = num_counting + 1 |
- else: |
- # access.mode == 'exclusive' |
- if num_excl > 0 or num_counting > 0: |
- break |
- else: |
- num_excl = num_excl + 1 |
- |
- del self.waiting[0] |
- reactor.callLater(0, d.callback, self) |
- |
- def waitUntilMaybeAvailable(self, owner, access): |
- """Fire when the lock *might* be available. The caller will need to |
- check with isAvailable() when the deferred fires. This loose form is |
- used to avoid deadlocks. If we were interested in a stronger form, |
- this would be named 'waitUntilAvailable', and the deferred would fire |
- after the lock had been claimed. |
- """ |
- debuglog("%s waitUntilAvailable(%s)" % (self, owner)) |
- assert isinstance(access, LockAccess) |
- if self.isAvailable(access): |
- return defer.succeed(self) |
- d = defer.Deferred() |
- self.waiting.append((access, d)) |
- return d |
- |
- |
-class RealMasterLock(BaseLock): |
- def __init__(self, lockid): |
- BaseLock.__init__(self, lockid.name, lockid.maxCount) |
- self.description = "<MasterLock(%s, %s)>" % (self.name, self.maxCount) |
- |
- def getLock(self, slave): |
- return self |
- |
-class RealSlaveLock: |
- def __init__(self, lockid): |
- self.name = lockid.name |
- self.maxCount = lockid.maxCount |
- self.maxCountForSlave = lockid.maxCountForSlave |
- self.description = "<SlaveLock(%s, %s, %s)>" % (self.name, |
- self.maxCount, |
- self.maxCountForSlave) |
- self.locks = {} |
- |
- def __repr__(self): |
- return self.description |
- |
- def getLock(self, slavebuilder): |
- slavename = slavebuilder.slave.slavename |
- if not self.locks.has_key(slavename): |
- maxCount = self.maxCountForSlave.get(slavename, |
- self.maxCount) |
- lock = self.locks[slavename] = BaseLock(self.name, maxCount) |
- desc = "<SlaveLock(%s, %s)[%s] %d>" % (self.name, maxCount, |
- slavename, id(lock)) |
- lock.description = desc |
- self.locks[slavename] = lock |
- return self.locks[slavename] |
- |
- |
-class LockAccess(util.ComparableMixin): |
- """ I am an object representing a way to access a lock. |
- |
- @param lockid: LockId instance that should be accessed. |
- @type lockid: A MasterLock or SlaveLock instance. |
- |
- @param mode: Mode of accessing the lock. |
- @type mode: A string, either 'counting' or 'exclusive'. |
- """ |
- |
- compare_attrs = ['lockid', 'mode'] |
- def __init__(self, lockid, mode): |
- self.lockid = lockid |
- self.mode = mode |
- |
- assert isinstance(lockid, (MasterLock, SlaveLock)) |
- assert mode in ['counting', 'exclusive'] |
- |
- |
-class BaseLockId(util.ComparableMixin): |
- """ Abstract base class for LockId classes. |
- |
- Sets up the 'access()' function for the LockId's available to the user |
- (MasterLock and SlaveLock classes). |
- Derived classes should add |
- - Comparison with the L{util.ComparableMixin} via the L{compare_attrs} |
- class variable. |
- - Link to the actual lock class should be added with the L{lockClass} |
- class variable. |
- """ |
- def access(self, mode): |
- """ Express how the lock should be accessed """ |
- assert mode in ['counting', 'exclusive'] |
- return LockAccess(self, mode) |
- |
- def defaultAccess(self): |
- """ For buildbot 0.7.7 compability: When user doesn't specify an access |
- mode, this one is chosen. |
- """ |
- return self.access('counting') |
- |
- |
- |
-# master.cfg should only reference the following MasterLock and SlaveLock |
-# classes. They are identifiers that will be turned into real Locks later, |
-# via the BotMaster.getLockByID method. |
- |
-class MasterLock(BaseLockId): |
- """I am a semaphore that limits the number of simultaneous actions. |
- |
- Builds and BuildSteps can declare that they wish to claim me as they run. |
- Only a limited number of such builds or steps will be able to run |
- simultaneously. By default this number is one, but my maxCount parameter |
- can be raised to allow two or three or more operations to happen at the |
- same time. |
- |
- Use this to protect a resource that is shared among all builders and all |
- slaves, for example to limit the load on a common SVN repository. |
- """ |
- |
- compare_attrs = ['name', 'maxCount'] |
- lockClass = RealMasterLock |
- def __init__(self, name, maxCount=1): |
- self.name = name |
- self.maxCount = maxCount |
- |
-class SlaveLock(BaseLockId): |
- """I am a semaphore that limits simultaneous actions on each buildslave. |
- |
- Builds and BuildSteps can declare that they wish to claim me as they run. |
- Only a limited number of such builds or steps will be able to run |
- simultaneously on any given buildslave. By default this number is one, |
- but my maxCount parameter can be raised to allow two or three or more |
- operations to happen on a single buildslave at the same time. |
- |
- Use this to protect a resource that is shared among all the builds taking |
- place on each slave, for example to limit CPU or memory load on an |
- underpowered machine. |
- |
- Each buildslave will get an independent copy of this semaphore. By |
- default each copy will use the same owner count (set with maxCount), but |
- you can provide maxCountForSlave with a dictionary that maps slavename to |
- owner count, to allow some slaves more parallelism than others. |
- |
- """ |
- |
- compare_attrs = ['name', 'maxCount', '_maxCountForSlaveList'] |
- lockClass = RealSlaveLock |
- def __init__(self, name, maxCount=1, maxCountForSlave={}): |
- self.name = name |
- self.maxCount = maxCount |
- self.maxCountForSlave = maxCountForSlave |
- # for comparison purposes, turn this dictionary into a stably-sorted |
- # list of tuples |
- self._maxCountForSlaveList = self.maxCountForSlave.items() |
- self._maxCountForSlaveList.sort() |
- self._maxCountForSlaveList = tuple(self._maxCountForSlaveList) |