From 8275f739c0ff534c82e8ca301bbb723e9583639a Mon Sep 17 00:00:00 2001 From: Robert Zubeck Date: Mon, 23 Jul 2007 17:09:08 +0000 Subject: [PATCH] Wrapper for peer network operations that need to acquire and release resource locks. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4780 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../presents/peer/server/PeerManager.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/java/com/threerings/presents/peer/server/PeerManager.java b/src/java/com/threerings/presents/peer/server/PeerManager.java index beb31daa3..68a1dcb95 100644 --- a/src/java/com/threerings/presents/peer/server/PeerManager.java +++ b/src/java/com/threerings/presents/peer/server/PeerManager.java @@ -109,6 +109,25 @@ public class PeerManager public void apply (NodeObject nodeobj); } + /** + * Wraps an operation that needs a shared resource lock to be acquired before it can be + * performed, and released after it completes. Used by {@link #performWithLock}. + */ + public static interface LockedOperation + { + /** + * Called when the resource lock was acquired successfully. The lock will be released + * immediately after this function call finishes. + */ + public void run (); + + /** + * Called when the resource lock was not acquired successfully, with the name of the peer + * who is holding the lock (or null in case of a generic failure). + */ + public void fail (String peerName); + } + /** * Creates a peer manager which will create a {@link NodeRepository} which will be used to * publish our existence and discover the other nodes. @@ -502,6 +521,34 @@ public class PeerManager return null; } + /** + * Tries to acquire the resource lock and, if successful, performs the operation and releases + * the lock; if unsuccessful, calls the operation's failure handler. Please note: the lock will + * be released immediately after the operation. + */ + public void performWithLock (final NodeObject.Lock lock, final LockedOperation operation) + { + acquireLock(lock, new ResultListener() { + public void requestCompleted (String nodeName) { + if (getNodeObject().nodeName.equals(nodeName)) { + // lock acquired successfully - perform the operation, and release the lock. + operation.run(); + releaseLock(lock, new ResultListener.NOOP()); + } else { + // some other peer beat us to it + operation.fail(nodeName); + if (nodeName == null) { + log.warning("Lock acquired by null? [lock=" + lock + "]."); + } + } + } + public void requestFailed (Exception cause) { + log.log(Level.WARNING, "Lock acquisition failed [lock=" + lock + "].", cause); + operation.fail(null); + } + }); + } + /** * Adds an observer to notify when this peer has been forced to drop a lock immediately. */