1/* GENERATED SOURCE. DO NOT MODIFY. */ 2// © 2016 and later: Unicode, Inc. and others. 3// License & terms of use: http://www.unicode.org/copyright.html#License 4/** 5 ******************************************************************************* 6 * Copyright (C) 2001-2013, International Business Machines Corporation and * 7 * others. All Rights Reserved. * 8 ******************************************************************************* 9 */ 10package android.icu.impl; 11 12import java.util.concurrent.locks.ReentrantReadWriteLock; 13 14 15/** 16 * <p>A Reader/Writer lock originally written for ICU service 17 * implementation. The internal implementation was replaced 18 * with the JDK's stock read write lock (ReentrantReadWriteLock) 19 * for ICU 52.</p> 20 * 21 * <p>This assumes that there will be little writing contention. 22 * It also doesn't allow active readers to acquire and release 23 * a write lock, or deal with priority inversion issues.</p> 24 * 25 * <p>Access to the lock should be enclosed in a try/finally block 26 * in order to ensure that the lock is always released in case of 27 * exceptions:<br><pre> 28 * try { 29 * lock.acquireRead(); 30 * // use service protected by the lock 31 * } 32 * finally { 33 * lock.releaseRead(); 34 * } 35 * </pre></p> 36 * 37 * <p>The lock provides utility methods getStats and clearStats 38 * to return statistics on the use of the lock.</p> 39 * @hide Only a subset of ICU is exposed in Android 40 */ 41public class ICURWLock { 42 private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); 43 44 private Stats stats = null; 45 46 /** 47 * Internal class used to gather statistics on the RWLock. 48 */ 49 public final static class Stats { 50 /** 51 * Number of times read access granted (read count). 52 */ 53 public int _rc; 54 55 /** 56 * Number of times concurrent read access granted (multiple read count). 57 */ 58 public int _mrc; 59 60 /** 61 * Number of times blocked for read (waiting reader count). 62 */ 63 public int _wrc; // wait for read 64 65 /** 66 * Number of times write access granted (writer count). 67 */ 68 public int _wc; 69 70 /** 71 * Number of times blocked for write (waiting writer count). 72 */ 73 public int _wwc; 74 75 private Stats() { 76 } 77 78 private Stats(int rc, int mrc, int wrc, int wc, int wwc) { 79 this._rc = rc; 80 this._mrc = mrc; 81 this._wrc = wrc; 82 this._wc = wc; 83 this._wwc = wwc; 84 } 85 86 private Stats(Stats rhs) { 87 this(rhs._rc, rhs._mrc, rhs._wrc, rhs._wc, rhs._wwc); 88 } 89 90 /** 91 * Return a string listing all the stats. 92 */ 93 @Override 94 public String toString() { 95 return " rc: " + _rc + 96 " mrc: " + _mrc + 97 " wrc: " + _wrc + 98 " wc: " + _wc + 99 " wwc: " + _wwc; 100 } 101 } 102 103 /** 104 * Reset the stats. Returns existing stats, if any. 105 */ 106 public synchronized Stats resetStats() { 107 Stats result = stats; 108 stats = new Stats(); 109 return result; 110 } 111 112 /** 113 * Clear the stats (stop collecting stats). Returns existing stats, if any. 114 */ 115 public synchronized Stats clearStats() { 116 Stats result = stats; 117 stats = null; 118 return result; 119 } 120 121 /** 122 * Return a snapshot of the current stats. This does not reset the stats. 123 */ 124 public synchronized Stats getStats() { 125 return stats == null ? null : new Stats(stats); 126 } 127 128 /** 129 * <p>Acquire a read lock, blocking until a read lock is 130 * available. Multiple readers can concurrently hold the read 131 * lock.</p> 132 * 133 * <p>If there's a writer, or a waiting writer, increment the 134 * waiting reader count and block on this. Otherwise 135 * increment the active reader count and return. Caller must call 136 * releaseRead when done (for example, in a finally block).</p> 137 */ 138 public void acquireRead() { 139 if (stats != null) { // stats is null by default 140 synchronized (this) { 141 stats._rc++; 142 if (rwl.getReadLockCount() > 0) { 143 stats._mrc++; 144 } 145 if (rwl.isWriteLocked()) { 146 stats._wrc++; 147 } 148 } 149 } 150 rwl.readLock().lock(); 151 } 152 153 /** 154 * <p>Release a read lock and return. An error will be thrown 155 * if a read lock is not currently held.</p> 156 * 157 * <p>If this is the last active reader, notify the oldest 158 * waiting writer. Call when finished with work 159 * controlled by acquireRead.</p> 160 */ 161 public void releaseRead() { 162 rwl.readLock().unlock(); 163 } 164 165 /** 166 * <p>Acquire the write lock, blocking until the write lock is 167 * available. Only one writer can acquire the write lock, and 168 * when held, no readers can acquire the read lock.</p> 169 * 170 * <p>If there are no readers and no waiting writers, mark as 171 * having an active writer and return. Otherwise, add a lock to the 172 * end of the waiting writer list, and block on it. Caller 173 * must call releaseWrite when done (for example, in a finally 174 * block).<p> 175 */ 176 public void acquireWrite() { 177 if (stats != null) { // stats is null by default 178 synchronized (this) { 179 stats._wc++; 180 if (rwl.getReadLockCount() > 0 || rwl.isWriteLocked()) { 181 stats._wwc++; 182 } 183 } 184 } 185 rwl.writeLock().lock(); 186 } 187 188 /** 189 * <p>Release the write lock and return. An error will be thrown 190 * if the write lock is not currently held.</p> 191 * 192 * <p>If there are waiting readers, make them all active and 193 * notify all of them. Otherwise, notify the oldest waiting 194 * writer, if any. Call when finished with work controlled by 195 * acquireWrite.</p> 196 */ 197 public void releaseWrite() { 198 rwl.writeLock().unlock(); 199 } 200} 201