You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Lock.java 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. package org.apache.archiva.common.filelock;
  2. /*
  3. * Licensed to the Apache Software Foundation (ASF) under one
  4. * or more contributor license agreements. See the NOTICE file
  5. * distributed with this work for additional information
  6. * regarding copyright ownership. The ASF licenses this file
  7. * to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance
  9. * with the License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing,
  14. * software distributed under the License is distributed on an
  15. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  16. * KIND, either express or implied. See the License for the
  17. * specific language governing permissions and limitations
  18. * under the License.
  19. */
  20. import java.io.Closeable;
  21. import java.io.IOException;
  22. import java.nio.channels.FileChannel;
  23. import java.nio.channels.FileLock;
  24. import java.nio.file.Path;
  25. import java.nio.file.StandardOpenOption;
  26. import java.util.HashMap;
  27. import java.util.Map;
  28. import java.util.concurrent.atomic.AtomicBoolean;
  29. import java.util.concurrent.atomic.AtomicInteger;
  30. /**
  31. * @author Olivier Lamy
  32. * @since 2.0.0
  33. */
  34. public class Lock implements Closeable
  35. {
  36. private Path file;
  37. private AtomicBoolean write;
  38. private final Map<Thread, AtomicInteger> fileClients = new HashMap<>();
  39. private FileLock fileLock;
  40. private FileChannel fileChannel;
  41. public Lock( Path file )
  42. {
  43. this.file = file;
  44. }
  45. public Lock( Path file, boolean write )
  46. throws IOException
  47. {
  48. this.file = file;
  49. this.write = new AtomicBoolean( write );
  50. fileChannel = write ? FileChannel.open(file, StandardOpenOption.WRITE, StandardOpenOption.READ) : FileChannel.open(file, StandardOpenOption.READ);
  51. }
  52. public Path getFile()
  53. {
  54. return file;
  55. }
  56. public AtomicBoolean isWrite()
  57. {
  58. return write;
  59. }
  60. public void setFile( Path file )
  61. {
  62. this.file = file;
  63. }
  64. public void setWrite( boolean write )
  65. {
  66. this.write.set( write );
  67. }
  68. public boolean isShared()
  69. {
  70. return this.fileLock.isValid() && this.fileLock.isShared();
  71. }
  72. public boolean isValid()
  73. {
  74. return this.fileLock!=null && this.fileLock.isValid();
  75. }
  76. public Map<Thread, AtomicInteger> getFileClients()
  77. {
  78. return fileClients;
  79. }
  80. public void addFileClient( Thread thread )
  81. {
  82. this.fileClients.put( thread, new AtomicInteger( 1 ) );
  83. }
  84. public boolean removeFileClient( Thread thread )
  85. {
  86. return this.fileClients.remove( thread ) != null;
  87. }
  88. public void close()
  89. throws IOException
  90. {
  91. IOException ioException = null;
  92. try
  93. {
  94. if (this.fileLock!=null) {
  95. this.fileLock.release();
  96. }
  97. }
  98. catch ( IOException e )
  99. {
  100. ioException = e;
  101. } finally {
  102. closeQuietly( fileChannel );
  103. fileClients.remove( Thread.currentThread() );
  104. }
  105. if ( ioException != null )
  106. {
  107. throw ioException;
  108. }
  109. }
  110. protected void openLock( boolean write, boolean timeout )
  111. throws IOException
  112. {
  113. fileClients.put( Thread.currentThread(), new AtomicInteger( 1 ) );
  114. this.fileLock = timeout
  115. ? fileChannel.tryLock( 0L, Long.MAX_VALUE, write ? false : true )
  116. : fileChannel.lock( 0L, Long.MAX_VALUE, write ? false : true );
  117. }
  118. private void closeQuietly( Closeable closeable )
  119. {
  120. try
  121. {
  122. closeable.close();
  123. }
  124. catch ( IOException e )
  125. {
  126. // ignore
  127. }
  128. }
  129. @Override
  130. public String toString()
  131. {
  132. final StringBuilder sb = new StringBuilder( "Lock{" );
  133. sb.append( "file=" ).append( file );
  134. sb.append( '}' );
  135. return sb.toString();
  136. }
  137. }