| | |
| | | * |
| | | * @author Ulysses |
| | | * @version 0.1 |
| | | * @since 2006/5/18 ¤W¤È 10:27:24 |
| | | * @since 2006/5/18 |
| | | */ |
| | | public class Lock |
| | | { |
| | | public class Lock { |
| | | Logger logger = LogManager.getLogger("com.ximple.io.dgn7"); |
| | | |
| | | /** |
| | |
| | | * @return |
| | | * @throws java.io.IOException |
| | | */ |
| | | synchronized boolean canRead() throws IOException |
| | | { |
| | | if ((writer != null) && (writer != Thread.currentThread())) |
| | | { |
| | | synchronized boolean canRead() throws IOException { |
| | | if ((writer != null) && (writer != Thread.currentThread())) { |
| | | return false; |
| | | } |
| | | |
| | | if (writer == null) |
| | | { |
| | | if (writer == null) { |
| | | return true; |
| | | } |
| | | |
| | | if (owners.size() > 1) |
| | | { |
| | | if (owners.size() > 1) { |
| | | return false; |
| | | } |
| | | |
| | |
| | | * @return |
| | | * @throws IOException |
| | | */ |
| | | synchronized boolean canWrite() throws IOException |
| | | { |
| | | if (owners.size() > 1) |
| | | { |
| | | synchronized boolean canWrite() throws IOException { |
| | | if (owners.size() > 1) { |
| | | return false; |
| | | } |
| | | |
| | | if ((canRead()) && ((writer == Thread.currentThread()) || (writer == null))) |
| | | { |
| | | if (owners.isEmpty()) |
| | | { |
| | | if ((canRead()) && ((writer == Thread.currentThread()) || (writer == null))) { |
| | | if (owners.isEmpty()) { |
| | | return true; |
| | | } |
| | | |
| | | if (owners.containsKey(Thread.currentThread())) |
| | | { |
| | | if (owners.containsKey(Thread.currentThread())) { |
| | | return true; |
| | | } |
| | | } |
| | |
| | | * |
| | | * @throws IOException |
| | | */ |
| | | public synchronized void lockRead() throws IOException |
| | | { |
| | | if (!canRead()) |
| | | { |
| | | while ((writeLocks > 0) || (writer != null)) |
| | | { |
| | | try |
| | | { |
| | | public synchronized void lockRead() throws IOException { |
| | | if (!canRead()) { |
| | | while ((writeLocks > 0) || (writer != null)) { |
| | | try { |
| | | wait(); |
| | | } catch (InterruptedException e) |
| | | { |
| | | } catch (InterruptedException e) { |
| | | throw (IOException) new IOException().initCause(e); |
| | | } |
| | | } |
| | |
| | | Thread current = Thread.currentThread(); |
| | | Owner owner = (Owner) owners.get(current); |
| | | |
| | | if (owner != null) |
| | | { |
| | | if (owner != null) { |
| | | owner.timesLocked++; |
| | | } else |
| | | { |
| | | } else { |
| | | owner = new Owner(current); |
| | | owners.put(current, owner); |
| | | } |
| | |
| | | logger.debug("Start Read Lock:" + owner); |
| | | } |
| | | |
| | | private void assertTrue(String message, boolean b) |
| | | { |
| | | if (!b) |
| | | { |
| | | private void assertTrue(String message, boolean b) { |
| | | if (!b) { |
| | | throw new AssertionError(message); |
| | | } |
| | | } |
| | |
| | | * Called by ShapefileReader after a read is complete and after the IOStream |
| | | * is closed. |
| | | */ |
| | | public synchronized void unlockRead() |
| | | { |
| | | public synchronized void unlockRead() { |
| | | assertTrue("Current thread does not have a readLock", owners.containsKey(Thread.currentThread())); |
| | | |
| | | Owner owner = (Owner) owners.get(Thread.currentThread()); |
| | |
| | | assertTrue("Current thread has " + owner.timesLocked + "negative number of locks", owner.timesLocked > 0); |
| | | owner.timesLocked--; |
| | | |
| | | if (owner.timesLocked == 0) |
| | | { |
| | | if (owner.timesLocked == 0) { |
| | | owners.remove(Thread.currentThread()); |
| | | } |
| | | |
| | |
| | | * |
| | | * @throws IOException |
| | | */ |
| | | public synchronized void lockWrite() throws IOException |
| | | { |
| | | public synchronized void lockWrite() throws IOException { |
| | | Thread currentThread = Thread.currentThread(); |
| | | |
| | | if (writer == null) |
| | | { |
| | | if (writer == null) { |
| | | writer = currentThread; |
| | | } |
| | | |
| | | while (!canWrite()) |
| | | { |
| | | try |
| | | { |
| | | while (!canWrite()) { |
| | | try { |
| | | wait(); |
| | | } catch (InterruptedException e) |
| | | { |
| | | } catch (InterruptedException e) { |
| | | throw (IOException) new IOException().initCause(e); |
| | | } |
| | | |
| | | if (writer == null) |
| | | { |
| | | if (writer == null) { |
| | | writer = currentThread; |
| | | } |
| | | } |
| | | |
| | | if (writer == null) |
| | | { |
| | | if (writer == null) { |
| | | writer = currentThread; |
| | | } |
| | | |
| | |
| | | /** |
| | | * default visibility for tests |
| | | */ |
| | | synchronized int getReadLocks(Thread thread) |
| | | { |
| | | synchronized int getReadLocks(Thread thread) { |
| | | Owner owner = (Owner) owners.get(thread); |
| | | |
| | | if (owner == null) |
| | | { |
| | | if (owner == null) { |
| | | return -1; |
| | | } |
| | | |
| | | return owner.timesLocked; |
| | | } |
| | | |
| | | public synchronized void unlockWrite() |
| | | { |
| | | if (writeLocks > 0) |
| | | { |
| | | public synchronized void unlockWrite() { |
| | | if (writeLocks > 0) { |
| | | assertTrue("current thread does not own the write lock", writer == Thread.currentThread()); |
| | | assertTrue("writeLock has already been unlocked", writeLocks > 0); |
| | | writeLocks--; |
| | | |
| | | if (writeLocks == 0) |
| | | { |
| | | if (writeLocks == 0) { |
| | | writer = null; |
| | | } |
| | | } |
| | |
| | | /** |
| | | * default visibility for tests |
| | | */ |
| | | synchronized boolean ownWriteLock(Thread thread) |
| | | { |
| | | synchronized boolean ownWriteLock(Thread thread) { |
| | | return (writer == thread) && (writeLocks > 0); |
| | | } |
| | | |
| | | private class Owner |
| | | { |
| | | private class Owner { |
| | | final Thread owner; |
| | | int timesLocked; |
| | | |
| | | Owner(Thread owner) |
| | | { |
| | | Owner(Thread owner) { |
| | | this.owner = owner; |
| | | timesLocked = 1; |
| | | } |
| | | |
| | | public String toString() |
| | | { |
| | | public String toString() { |
| | | return owner.getName() + " has " + timesLocked + " locks"; |
| | | } |
| | | } |