1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.transaction.locking;
18
19 import org.apache.commons.transaction.util.LoggerFacade;
20
21 /**
22 * Manager for
23 * {@link org.apache.commons.transaction.locking.ReadWriteUpgradeLock}s on
24 * resources. <br>
25 * <br>
26 * <p>
27 * The idea (as explained by Jim LoVerde) is that only one owner can hold an
28 * upgrade lock, but while that is held, it is possible for read locks to exist
29 * and/or be obtained, and when the request is made to upgrade to a write lock
30 * by the same owner, the lock manager prevents additional read locks until the
31 * write lock can be aquired.
32 * </p>
33 * <p>
34 * In this sense the write lock becomes preferred over all other locks when it gets upgraded from
35 * a upgrate lock. Preferred means that if it has to wait and others wait as well it will be
36 * served before all other none preferred locking requests.
37 * </p>
38 *
39 * @version $Id: ReadWriteUpgradeLockManager.java 493628 2007-01-07 01:42:48Z joerg $
40 *
41 * @see ReadWriteUpgradeLock
42 * @since 1.1
43 */
44 public class ReadWriteUpgradeLockManager extends ReadWriteLockManager {
45
46 /**
47 * Creates a new read/write/upgrade lock manager.
48 *
49 * @param logger generic logger used for all kind of debug logging
50 * @param timeoutMSecs specifies the maximum time to wait for a lock in milliseconds
51 */
52 public ReadWriteUpgradeLockManager(LoggerFacade logger, long timeoutMSecs) {
53 super(ReadWriteUpgradeLock.WRITE_LOCK, logger, timeoutMSecs);
54 }
55
56 /**
57 * Tries to acquire a reentrant upgrade lock on a resource. <br>
58 * <br>
59 * This method does not block, but immediatly returns. If a lock is not
60 * available <code>false</code> will be returned.
61 *
62 * @param ownerId
63 * a unique id identifying the entity that wants to acquire this
64 * lock
65 * @param resourceId
66 * the resource to get the lock for
67 * @return <code>true</code> if the lock has been acquired, <code>false</code> otherwise
68 */
69 public boolean tryUpgradeLock(Object ownerId, Object resourceId) {
70 return tryLock(ownerId, resourceId, ReadWriteUpgradeLock.UPGRADE_LOCK, true);
71 }
72
73 /**
74 * Tries to acquire an exclusive, reentrant write lock on a resource. <br>
75 * <br>
76 * This method does not block, but immediatly returns. If a lock is not
77 * available <code>false</code> will be returned.
78 *
79 * @param ownerId
80 * a unique id identifying the entity that wants to acquire this
81 * lock
82 * @param resourceId
83 * the resource to get the lock for
84 * @return <code>true</code> if the lock has been acquired, <code>false</code> otherwise
85 */
86 public boolean tryWriteLock(Object ownerId, Object resourceId) {
87 return tryLock(ownerId, resourceId, ReadWriteUpgradeLock.WRITE_LOCK, true);
88 }
89
90 /**
91 * Tries to acquire a reentrant upgrade lock on a resource. <br>
92 * <br>
93 * This method blocks and waits for the lock in case it is not avaiable. If
94 * there is a timeout or a deadlock or the thread is interrupted a
95 * LockException is thrown.
96 *
97 * @param ownerId
98 * a unique id identifying the entity that wants to acquire this
99 * lock
100 * @param resourceId
101 * the resource to get the level for
102 * @throws LockException
103 * will be thrown when the lock can not be acquired
104 */
105 public void upgradeLock(Object ownerId, Object resourceId) throws LockException {
106 super.lock(ownerId, resourceId, ReadWriteUpgradeLock.UPGRADE_LOCK, true);
107 }
108
109 /**
110 * Tries to acquire an exclusive, reentrant write lock on a resource. <br>
111 * <br>
112 * This method blocks and waits for the lock in case it is not avaiable. If
113 * there is a timeout or a deadlock or the thread is interrupted a
114 * LockException is thrown.
115 *
116 * @param ownerId
117 * a unique id identifying the entity that wants to acquire this
118 * lock
119 * @param resourceId
120 * the resource to get the level for
121 * @throws LockException
122 * will be thrown when the lock can not be acquired
123 */
124 public void writeLock(Object ownerId, Object resourceId) throws LockException {
125 super.lock(ownerId, resourceId, ReadWriteUpgradeLock.WRITE_LOCK, true);
126 }
127
128 protected GenericLock createLock(Object resourceId) {
129 synchronized (globalLocks) {
130 GenericLock lock = new ReadWriteUpgradeLock(resourceId, logger);
131 globalLocks.put(resourceId, lock);
132 return lock;
133 }
134 }
135
136 }