Source Code Cross Referenced for NativeFSLockFactory.java in  » Net » lucene-connector » org » apache » lucene » store » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Net » lucene connector » org.apache.lucene.store 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.apache.lucene.store;
002:
003:        /**
004:         * Licensed to the Apache Software Foundation (ASF) under one or more
005:         * contributor license agreements.  See the NOTICE file distributed with
006:         * this work for additional information regarding copyright ownership.
007:         * The ASF licenses this file to You under the Apache License, Version 2.0
008:         * (the "License"); you may not use this file except in compliance with
009:         * the License.  You may obtain a copy of the License at
010:         *
011:         *     http://www.apache.org/licenses/LICENSE-2.0
012:         *
013:         * Unless required by applicable law or agreed to in writing, software
014:         * distributed under the License is distributed on an "AS IS" BASIS,
015:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016:         * See the License for the specific language governing permissions and
017:         * limitations under the License.
018:         */
019:
020:        import java.nio.channels.FileChannel;
021:        import java.nio.channels.FileLock;
022:        import java.io.File;
023:        import java.io.RandomAccessFile;
024:        import java.io.IOException;
025:        import java.util.HashSet;
026:        import java.util.Random;
027:
028:        /**
029:         * <p>Implements {@link LockFactory} using native OS file
030:         * locks.  Note that because this LockFactory relies on
031:         * java.nio.* APIs for locking, any problems with those APIs
032:         * will cause locking to fail.  Specifically, on certain NFS
033:         * environments the java.nio.* locks will fail (the lock can
034:         * incorrectly be double acquired) whereas {@link
035:         * SimpleFSLockFactory} worked perfectly in those same
036:         * environments.  For NFS based access to an index, it's
037:         * recommended that you try {@link SimpleFSLockFactory}
038:         * first and work around the one limitation that a lock file
039:         * could be left when the JVM exits abnormally.</p>
040:         *
041:         * <p>The primary benefit of {@link NativeFSLockFactory} is
042:         * that lock files will be properly removed (by the OS) if
043:         * the JVM has an abnormal exit.</p>
044:         * 
045:         * <p>Note that, unlike {@link SimpleFSLockFactory}, the existence of
046:         * leftover lock files in the filesystem on exiting the JVM
047:         * is fine because the OS will free the locks held against
048:         * these files even though the files still remain.</p>
049:         *
050:         * <p>If you suspect that this or any other LockFactory is
051:         * not working properly in your environment, you can easily
052:         * test it by using {@link VerifyingLockFactory}, {@link
053:         * LockVerifyServer} and {@link LockStressTest}.</p>
054:         *
055:         * @see LockFactory
056:         */
057:
058:        public class NativeFSLockFactory extends LockFactory {
059:
060:            /**
061:             * Directory specified by <code>org.apache.lucene.lockDir</code>
062:             * system property.  If that is not set, then <code>java.io.tmpdir</code>
063:             * system property is used.
064:             */
065:
066:            private File lockDir;
067:
068:            // Simple test to verify locking system is "working".  On
069:            // NFS, if it's misconfigured, you can hit long (35
070:            // second) timeouts which cause Lock.obtain to take far
071:            // too long (it assumes the obtain() call takes zero
072:            // time).  Since it's a configuration problem, we test up
073:            // front once on creating the LockFactory:
074:            private void acquireTestLock() throws IOException {
075:                String randomLockName = "lucene-"
076:                        + Long.toString(new Random().nextInt(),
077:                                Character.MAX_RADIX) + "-test.lock";
078:
079:                Lock l = makeLock(randomLockName);
080:                try {
081:                    l.obtain();
082:                } catch (IOException e) {
083:                    IOException e2 = new IOException(
084:                            "Failed to acquire random test lock; please verify filesystem for lock directory '"
085:                                    + lockDir + "' supports locking");
086:                    e2.initCause(e);
087:                    throw e2;
088:                }
089:
090:                l.release();
091:            }
092:
093:            /**
094:             * Create a NativeFSLockFactory instance, with null (unset)
095:             * lock directory.  This is package-private and is only
096:             * used by FSDirectory when creating this LockFactory via
097:             * the System property
098:             * org.apache.lucene.store.FSDirectoryLockFactoryClass.
099:             */
100:            NativeFSLockFactory() throws IOException {
101:                this ((File) null);
102:            }
103:
104:            /**
105:             * Create a NativeFSLockFactory instance, storing lock
106:             * files into the specified lockDirName:
107:             *
108:             * @param lockDirName where lock files are created.
109:             */
110:            public NativeFSLockFactory(String lockDirName) throws IOException {
111:                this (new File(lockDirName));
112:            }
113:
114:            /**
115:             * Create a NativeFSLockFactory instance, storing lock
116:             * files into the specified lockDir:
117:             * 
118:             * @param lockDir where lock files are created.
119:             */
120:            public NativeFSLockFactory(File lockDir) throws IOException {
121:                setLockDir(lockDir);
122:            }
123:
124:            /**
125:             * Set the lock directory.  This is package-private and is
126:             * only used externally by FSDirectory when creating this
127:             * LockFactory via the System property
128:             * org.apache.lucene.store.FSDirectoryLockFactoryClass.
129:             */
130:            void setLockDir(File lockDir) throws IOException {
131:                this .lockDir = lockDir;
132:                if (lockDir != null) {
133:                    // Ensure that lockDir exists and is a directory.
134:                    if (!lockDir.exists()) {
135:                        if (!lockDir.mkdirs())
136:                            throw new IOException("Cannot create directory: "
137:                                    + lockDir.getAbsolutePath());
138:                    } else if (!lockDir.isDirectory()) {
139:                        throw new IOException(
140:                                "Found regular file where directory expected: "
141:                                        + lockDir.getAbsolutePath());
142:                    }
143:
144:                    acquireTestLock();
145:                }
146:            }
147:
148:            public synchronized Lock makeLock(String lockName) {
149:                if (lockPrefix != null)
150:                    lockName = lockPrefix + "-n-" + lockName;
151:                return new NativeFSLock(lockDir, lockName);
152:            }
153:
154:            public void clearLock(String lockName) throws IOException {
155:                // Note that this isn't strictly required anymore
156:                // because the existence of these files does not mean
157:                // they are locked, but, still do this in case people
158:                // really want to see the files go away:
159:                if (lockDir.exists()) {
160:                    if (lockPrefix != null) {
161:                        lockName = lockPrefix + "-n-" + lockName;
162:                    }
163:                    File lockFile = new File(lockDir, lockName);
164:                    if (lockFile.exists() && !lockFile.delete()) {
165:                        throw new IOException("Cannot delete " + lockFile);
166:                    }
167:                }
168:            }
169:        };
170:
171:        class NativeFSLock extends Lock {
172:
173:            private RandomAccessFile f;
174:            private FileChannel channel;
175:            private FileLock lock;
176:            private File path;
177:            private File lockDir;
178:
179:            /*
180:             * The javadocs for FileChannel state that you should have
181:             * a single instance of a FileChannel (per JVM) for all
182:             * locking against a given file.  To ensure this, we have
183:             * a single (static) HashSet that contains the file paths
184:             * of all currently locked locks.  This protects against
185:             * possible cases where different Directory instances in
186:             * one JVM (each with their own NativeFSLockFactory
187:             * instance) have set the same lock dir and lock prefix.
188:             */
189:            private static HashSet LOCK_HELD = new HashSet();
190:
191:            public NativeFSLock(File lockDir, String lockFileName) {
192:                this .lockDir = lockDir;
193:                path = new File(lockDir, lockFileName);
194:            }
195:
196:            public synchronized boolean obtain() throws IOException {
197:
198:                if (isLocked()) {
199:                    // Our instance is already locked:
200:                    return false;
201:                }
202:
203:                // Ensure that lockDir exists and is a directory.
204:                if (!lockDir.exists()) {
205:                    if (!lockDir.mkdirs())
206:                        throw new IOException("Cannot create directory: "
207:                                + lockDir.getAbsolutePath());
208:                } else if (!lockDir.isDirectory()) {
209:                    throw new IOException(
210:                            "Found regular file where directory expected: "
211:                                    + lockDir.getAbsolutePath());
212:                }
213:
214:                String canonicalPath = path.getCanonicalPath();
215:
216:                boolean markedHeld = false;
217:
218:                try {
219:
220:                    // Make sure nobody else in-process has this lock held
221:                    // already, and, mark it held if not:
222:
223:                    synchronized (LOCK_HELD) {
224:                        if (LOCK_HELD.contains(canonicalPath)) {
225:                            // Someone else in this JVM already has the lock:
226:                            return false;
227:                        } else {
228:                            // This "reserves" the fact that we are the one
229:                            // thread trying to obtain this lock, so we own
230:                            // the only instance of a channel against this
231:                            // file:
232:                            LOCK_HELD.add(canonicalPath);
233:                            markedHeld = true;
234:                        }
235:                    }
236:
237:                    try {
238:                        f = new RandomAccessFile(path, "rw");
239:                    } catch (IOException e) {
240:                        // On Windows, we can get intermittant "Access
241:                        // Denied" here.  So, we treat this as failure to
242:                        // acquire the lock, but, store the reason in case
243:                        // there is in fact a real error case.
244:                        failureReason = e;
245:                        f = null;
246:                    }
247:
248:                    if (f != null) {
249:                        try {
250:                            channel = f.getChannel();
251:                            try {
252:                                lock = channel.tryLock();
253:                            } catch (IOException e) {
254:                                // At least on OS X, we will sometimes get an
255:                                // intermittant "Permission Denied" IOException,
256:                                // which seems to simply mean "you failed to get
257:                                // the lock".  But other IOExceptions could be
258:                                // "permanent" (eg, locking is not supported via
259:                                // the filesystem).  So, we record the failure
260:                                // reason here; the timeout obtain (usually the
261:                                // one calling us) will use this as "root cause"
262:                                // if it fails to get the lock.
263:                                failureReason = e;
264:                            } finally {
265:                                if (lock == null) {
266:                                    try {
267:                                        channel.close();
268:                                    } finally {
269:                                        channel = null;
270:                                    }
271:                                }
272:                            }
273:                        } finally {
274:                            if (channel == null) {
275:                                try {
276:                                    f.close();
277:                                } finally {
278:                                    f = null;
279:                                }
280:                            }
281:                        }
282:                    }
283:
284:                } finally {
285:                    if (markedHeld && !isLocked()) {
286:                        synchronized (LOCK_HELD) {
287:                            if (LOCK_HELD.contains(canonicalPath)) {
288:                                LOCK_HELD.remove(canonicalPath);
289:                            }
290:                        }
291:                    }
292:                }
293:                return isLocked();
294:            }
295:
296:            public synchronized void release() throws IOException {
297:                if (isLocked()) {
298:                    try {
299:                        lock.release();
300:                    } finally {
301:                        lock = null;
302:                        try {
303:                            channel.close();
304:                        } finally {
305:                            channel = null;
306:                            try {
307:                                f.close();
308:                            } finally {
309:                                f = null;
310:                                synchronized (LOCK_HELD) {
311:                                    LOCK_HELD.remove(path.getCanonicalPath());
312:                                }
313:                            }
314:                        }
315:                    }
316:                    if (!path.delete())
317:                        throw new LockReleaseFailedException(
318:                                "failed to delete " + path);
319:                }
320:            }
321:
322:            public synchronized boolean isLocked() {
323:                return lock != null;
324:            }
325:
326:            public String toString() {
327:                return "NativeFSLock@" + path;
328:            }
329:
330:            public void finalize() throws Throwable {
331:                try {
332:                    if (isLocked()) {
333:                        release();
334:                    }
335:                } finally {
336:                    super.finalize();
337:                }
338:            }
339:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.