[JGIT PATCH 10/13] Add compare-and-swap semantics to RefUpdate

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This permits the caller to set the value it expects to find in the
Ref upon obtaining the update lock.  If the ref value doesn't match
then the update is aborted with Result.LOCK_FAILURE, so the caller
can recover gracefully without making unexpected changes.

Signed-off-by: Shawn O. Pearce <spearce@xxxxxxxxxxx>
---
 .../src/org/spearce/jgit/lib/RefUpdate.java        |   30 ++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
index 235c2fd..0c9ce91 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
@@ -149,6 +149,9 @@
 	/** Old value of the ref, obtained after we lock it. */
 	private ObjectId oldValue;
 
+	/** If non-null, the value {@link #oldValue} must have to continue. */
+	private ObjectId expValue;
+
 	/** Result of the update operation. */
 	private Result result = Result.NOT_ATTEMPTED;
 
@@ -190,6 +193,27 @@ public void setNewObjectId(final AnyObjectId id) {
 	}
 
 	/**
+	 * @return the expected value of the ref after the lock is taken, but before
+	 *         update occurs. Null to avoid the compare and swap test. Use
+	 *         {@link ObjectId#zeroId()} to indicate expectation of a
+	 *         non-existant ref.
+	 */
+	public ObjectId getExpectedOldObjectId() {
+		return expValue;
+	}
+
+	/**
+	 * @param id
+	 *            the expected value of the ref after the lock is taken, but
+	 *            before update occurs. Null to avoid the compare and swap test.
+	 *            Use {@link ObjectId#zeroId()} to indicate expectation of a
+	 *            non-existant ref.
+	 */
+	public void setExpectedOldObjectId(final AnyObjectId id) {
+		expValue = id != null ? id.toObjectId() : null;
+	}
+
+	/**
 	 * Check if this update wants to forcefully change the ref.
 	 * 
 	 * @return true if this update should ignore merge tests.
@@ -370,6 +394,12 @@ private Result updateImpl(final RevWalk walk, final Store store)
 			return Result.LOCK_FAILURE;
 		try {
 			oldValue = db.idOf(getName());
+			if (expValue != null) {
+				final ObjectId o;
+				o = oldValue != null ? oldValue : ObjectId.zeroId();
+				if (!expValue.equals(o))
+					return Result.LOCK_FAILURE;
+			}
 			if (oldValue == null)
 				return store.store(lock, Result.NEW);
 
-- 
1.6.1.rc4.301.g5497a

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux