From 3d541ef320cb3861c62436d7f134f3e19dadc7c1 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Thu, 29 Oct 2009 12:13:44 +0300 Subject: [PATCH] win32fs fixed: cache is thread local --- .../vfs/impl/local/LocalFileSystemImpl.java | 2 - .../openapi/vfs/impl/win32/Win32Kernel.java | 45 +++++++++--------- .../vfs/impl/win32/Win32LocalFileSystem.java | 55 +++++++++++----------- 3 files changed, 52 insertions(+), 50 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java index 8fb0047b85..31c2208ee8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java @@ -23,7 +23,6 @@ import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.impl.win32.Win32LocalFileSystem; import com.intellij.openapi.vfs.newvfs.ManagingFS; import com.intellij.openapi.vfs.newvfs.NewVirtualFile; import com.intellij.openapi.vfs.newvfs.RefreshQueue; @@ -124,7 +123,6 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap } public void disposeComponent() { - Win32LocalFileSystem.release(); } @TestOnly diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32Kernel.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32Kernel.java index 7c6b330089..bad5d66e9c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32Kernel.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32Kernel.java @@ -35,16 +35,19 @@ import java.util.Map; public class Win32Kernel { private static final int MAX_PATH = 0x00000104; + public static final int FILE_ATTRIBUTE_DIRECTORY = 0x00000010; public static final int FILE_ATTRIBUTE_READONLY = 0x0001; - private Kernel32 myKernel = (Kernel32)Native.loadLibrary("kernel32", Kernel32.class, new HashMap() { + private static W32API.HANDLE INVALID_HANDLE_VALUE = new W32API.HANDLE(Pointer.createConstant(0xFFFFFFFFl)); + + private static Kernel32 myKernel = (Kernel32)Native.loadLibrary("kernel32", Kernel32.class, new HashMap() { { put(Library.OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE); put(Library.OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE); }}); - WIN32_FIND_DATA myData = new WIN32_FIND_DATA(); + private final WIN32_FIND_DATA myData = new WIN32_FIND_DATA(); private static class FileInfo { private FileInfo(WIN32_FIND_DATA data) { @@ -56,8 +59,6 @@ public class Win32Kernel { long ftLastWriteTime; } - private static W32API.HANDLE INVALID_HANDLE_VALUE = new W32API.HANDLE(Pointer.createConstant(0xFFFFFFFFl)); - private Map myCache = new HashMap(); public String[] list(String absolutePath) { @@ -65,22 +66,23 @@ public class Win32Kernel { myCache.clear(); ArrayList list = new ArrayList(); - W32API.HANDLE hFind = myKernel.FindFirstFile(absolutePath.replace('/', '\\') + "\\*", myData); + WIN32_FIND_DATA data = myData; + W32API.HANDLE hFind = myKernel.FindFirstFile(absolutePath.replace('/', '\\') + "\\*", data); if (hFind.equals(INVALID_HANDLE_VALUE)) return new String[0]; try { do { - String name = Native.toString(myData.cFileName); + String name = Native.toString(data.cFileName); if (name.equals(".")) { - myCache.put(absolutePath, new FileInfo(myData)); + myCache.put(absolutePath, new FileInfo(data)); continue; } else if (name.equals("..")) { continue; } - myCache.put(absolutePath + "/" + name, new FileInfo(myData)); + myCache.put(absolutePath + "/" + name, new FileInfo(data)); list.add(name); } - while (myKernel.FindNextFile(hFind, myData)); + while (myKernel.FindNextFile(hFind, data)); } finally { myKernel.FindClose(hFind); @@ -91,7 +93,7 @@ public class Win32Kernel { public boolean exists(String path) { myCache.clear(); try { - getData(path); + getInfo(path); return true; } catch (FileNotFoundException e) { @@ -100,35 +102,36 @@ public class Win32Kernel { } public boolean isDirectory(String path) throws FileNotFoundException { - FileInfo data = getData(path); + FileInfo data = getInfo(path); return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; } public boolean isWritable(String path) throws FileNotFoundException { - return (getData(path).dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0; + return (getInfo(path).dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0; } public long getTimeStamp(String path) throws FileNotFoundException { - return getData(path).ftLastWriteTime; + return getInfo(path).ftLastWriteTime; } - private FileInfo getData(String path) throws FileNotFoundException { - FileInfo data = myCache.get(path); - if (data == null) { + private FileInfo getInfo(String path) throws FileNotFoundException { + FileInfo info = myCache.get(path); + if (info == null) { myCache.clear(); - W32API.HANDLE handle = myKernel.FindFirstFile(path.replace('/', '\\'), myData); + WIN32_FIND_DATA data = myData; + W32API.HANDLE handle = myKernel.FindFirstFile(path.replace('/', '\\'), data); if (handle.equals(INVALID_HANDLE_VALUE)) { throw new FileNotFoundException(path); } myKernel.FindClose(handle); - data = new FileInfo(myData); - myCache.put(path, data); + info = new FileInfo(data); + myCache.put(path, info); } - return data; + return info; } public void release() throws Throwable { - myData.release(); + myData.release(); } public interface Kernel32 extends StdCallLibrary { diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java index 1141d8f18d..ae06e76cdd 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java @@ -21,6 +21,7 @@ import com.intellij.openapi.vfs.impl.local.LocalFileSystemBase; import org.jetbrains.annotations.NotNull; import java.io.FileNotFoundException; +import java.util.Arrays; import java.util.Collection; import java.util.Set; @@ -31,29 +32,19 @@ public class Win32LocalFileSystem extends LocalFileSystemBase { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.impl.win32.Win32LocalFileSystem"); - private static Win32LocalFileSystem ourSystem; - - public static Win32LocalFileSystem getWin32Instance() { - if (ourSystem == null) { - ourSystem = new Win32LocalFileSystem(); + private static final ThreadLocal THREAD_LOCAL = new ThreadLocal() { + @Override + protected Win32LocalFileSystem initialValue() { + return new Win32LocalFileSystem(); } - return ourSystem; - } + }; - public static void release() { - Win32LocalFileSystem system = ourSystem; - ourSystem = null; - if (system != null) { - try { - system.myKernel.release(); - } - catch (Throwable throwable) { - LOG.error(throwable); - } - } + public static Win32LocalFileSystem getWin32Instance() { + return THREAD_LOCAL.get(); } private final Win32Kernel myKernel = new Win32Kernel(); + private boolean checkMe = false; private Win32LocalFileSystem() { } @@ -62,11 +53,15 @@ public class Win32LocalFileSystem extends LocalFileSystemBase { public String[] list(VirtualFile file) { try { String[] strings = myKernel.list(file.getPath()); - //assert Arrays.asList(strings).equals(Arrays.asList(super.list(file))); + if (checkMe && !Arrays.asList(strings).equals(Arrays.asList(super.list(file)))) { + LOG.error(file.getPath()); + } return strings; } catch (Exception e) { -// assert false; + if (checkMe) { + assert false; + } return super.list(file); } } @@ -75,7 +70,9 @@ public class Win32LocalFileSystem extends LocalFileSystemBase { public boolean exists(VirtualFile fileOrDirectory) { if (fileOrDirectory.getParent() == null) return true; boolean b = myKernel.exists(fileOrDirectory.getPath()); - //assert b == super.exists(fileOrDirectory); + if (checkMe && b != super.exists(fileOrDirectory)) { + LOG.error(fileOrDirectory.getPath()); + } return b; } @@ -83,11 +80,12 @@ public class Win32LocalFileSystem extends LocalFileSystemBase { public boolean isDirectory(VirtualFile file) { try { boolean b = myKernel.isDirectory(file.getPath()); - //assert b == super.isDirectory(file); + if (checkMe && b != super.isDirectory(file)) { + LOG.error(file.getPath()); + } return b; } catch (FileNotFoundException e) { -// assert false; return super.isDirectory(file); } } @@ -96,11 +94,12 @@ public class Win32LocalFileSystem extends LocalFileSystemBase { public boolean isWritable(VirtualFile file) { try { boolean b = myKernel.isWritable(file.getPath()); - //assert b == super.isWritable(file); + if (checkMe && b != super.isWritable(file)) { + LOG.error(file.getPath()); + } return b; } catch (FileNotFoundException e) { -// assert false: file; return super.isWritable(file); } } @@ -109,11 +108,13 @@ public class Win32LocalFileSystem extends LocalFileSystemBase { public long getTimeStamp(VirtualFile file) { try { long timeStamp = myKernel.getTimeStamp(file.getPath()); - //assert timeStamp == super.getTimeStamp(file); + if (checkMe && timeStamp != super.getTimeStamp(file)) { + timeStamp = myKernel.getTimeStamp(file.getPath()); + LOG.error(file.getPath()); + } return timeStamp; } catch (FileNotFoundException e) { -// assert false; return super.getTimeStamp(file); } } -- 2.11.4.GIT