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