#66712: Make sure that we do not access FileObject synchronized methods under BLD200511061900
authormentlicher@netbeans.org
Fri, 04 Nov 2005 18:26:04 +0000
changeset 6519d1b26104ae34
parent 6518 357e3aaf8b50
child 6520 198e591ed8df
#66712: Make sure that we do not access FileObject synchronized methods under
synchronizations on Memory.class. Because methods acquiring Memory.class
synchronizations can be called under FileObject synchronization.
vcscore/nbproject/project.properties
vcscore/src/org/netbeans/modules/vcscore/turbo/local/FileAttributeQuery.java
vcscore/src/org/netbeans/modules/vcscore/turbo/local/Memory.java
     1.1 --- a/vcscore/nbproject/project.properties	Fri Nov 04 17:48:21 2005 +0000
     1.2 +++ b/vcscore/nbproject/project.properties	Fri Nov 04 18:26:04 2005 +0000
     1.3 @@ -9,7 +9,7 @@
     1.4  # Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun
     1.5  # Microsystems, Inc. All Rights Reserved.
     1.6  
     1.7 -spec.version.base=1.16.6
     1.8 +spec.version.base=1.16.7
     1.9  is.autoload=true
    1.10  javadoc.apichanges=${basedir}/api/doc/changes/apichanges.xml
    1.11  javadoc.arch=${basedir}/arch/arch-vcscore.xml
     2.1 --- a/vcscore/src/org/netbeans/modules/vcscore/turbo/local/FileAttributeQuery.java	Fri Nov 04 17:48:21 2005 +0000
     2.2 +++ b/vcscore/src/org/netbeans/modules/vcscore/turbo/local/FileAttributeQuery.java	Fri Nov 04 18:26:04 2005 +0000
     2.3 @@ -385,11 +385,13 @@
     2.4                      String name = request.attribute;
     2.5                      Object value;
     2.6                      boolean fire;
     2.7 +                    fo = (FileObject) fo.getAttribute("VCS-Native-FileObject");  // NOI18N
     2.8                      if (Memory.existsEntry(fo, name)) {
     2.9 -
    2.10 -                        synchronized(Memory.class) {
    2.11 -                            fire = Memory.isLiveEntry(fo)  == false;
    2.12 -                            value = Memory.get(fo, name);
    2.13 +                        synchronized (fo) {
    2.14 +                            synchronized(Memory.class) {
    2.15 +                                fire = Memory.isLiveEntry(fo)  == false;
    2.16 +                                value = Memory.get(fo, name);
    2.17 +                            }
    2.18                          }
    2.19                          if (fire) {
    2.20                              Statistics.diskHit(); // from our perpective we achieved hit
    2.21 @@ -397,12 +399,14 @@
    2.22                      } else {
    2.23                          value = loadAttribute(fo, name, null);
    2.24                          // possible thread switch, so atomic fire test must be used
    2.25 -                        synchronized(Memory.class) {
    2.26 -                            fire = Memory.isLiveEntry(fo)  == false;
    2.27 -                            Object oldValue = Memory.get(fo, name);
    2.28 -                            Memory.put(fo, name, value != null ? value : Memory.NULL);
    2.29 -                            fire |= (oldValue != null && !oldValue.equals(value))
    2.30 -                                 || (oldValue == null && value != null);
    2.31 +                        synchronized (fo) {
    2.32 +                            synchronized(Memory.class) {
    2.33 +                                fire = Memory.isLiveEntry(fo)  == false;
    2.34 +                                Object oldValue = Memory.get(fo, name);
    2.35 +                                Memory.put(fo, name, value != null ? value : Memory.NULL);
    2.36 +                                fire |= (oldValue != null && !oldValue.equals(value))
    2.37 +                                     || (oldValue == null && value != null);
    2.38 +                            }
    2.39                          }
    2.40                      }
    2.41  
     3.1 --- a/vcscore/src/org/netbeans/modules/vcscore/turbo/local/Memory.java	Fri Nov 04 17:48:21 2005 +0000
     3.2 +++ b/vcscore/src/org/netbeans/modules/vcscore/turbo/local/Memory.java	Fri Nov 04 18:26:04 2005 +0000
     3.3 @@ -83,41 +83,45 @@
     3.4      }
     3.5  
     3.6      /** Entry 'format' does not keep any strong ref to source file object. */
     3.7 -    private static synchronized void putEntry(FileObjectKey key, String name, Object value, Map[] speculativePtr) {
     3.8 +    private static void putEntry(FileObjectKey key, String name, Object value, Map[] speculativePtr) {
     3.9  
    3.10 -        // update existing values
    3.11 +        FileObject fo = key.fileObject;
    3.12 +        File f = FileUtil.toFile(fo);
    3.13 +        
    3.14 +        synchronized (Memory.class) {
    3.15 +            
    3.16 +            // update existing values
    3.17 +            Map attributes;
    3.18 +            if (liveFileObjectsMap.containsKey(key)) {
    3.19 +                attributes = (Map) liveFileObjectsMap.get(key);
    3.20 +                if (value != null) {
    3.21 +                    attributes.put(name, normalizeValue(value));
    3.22 +                } else {
    3.23 +                    attributes.remove(name);
    3.24 +                }
    3.25 +            } else {
    3.26 +                // merge with speculative values
    3.27  
    3.28 -        Map attributes;
    3.29 -        if (liveFileObjectsMap.containsKey(key)) {
    3.30 -            attributes = (Map) liveFileObjectsMap.get(key);
    3.31 -            if (value != null) {
    3.32 -                attributes.put(name, normalizeValue(value));
    3.33 -            } else {
    3.34 -                attributes.remove(name);
    3.35 +                String absolutePath = f.getAbsolutePath();
    3.36 +                attributes = (Map) speculativeCache.get(absolutePath);
    3.37 +                boolean hadSpeculative = false;
    3.38 +                if (attributes == null) {
    3.39 +                    attributes = new HashMap(5);
    3.40 +                } else {
    3.41 +                    hadSpeculative = true;
    3.42 +                }
    3.43 +                if (value != null) {
    3.44 +                    attributes.put(name, normalizeValue(value));
    3.45 +                } else {
    3.46 +                    attributes.remove(name);
    3.47 +                }
    3.48 +                liveFileObjectsMap.put(key, attributes);
    3.49 +                if (hadSpeculative) {
    3.50 +                    speculativeCache.remove(absolutePath);
    3.51 +                    speculativePtr[0] = new HashMap(attributes);
    3.52 +                }
    3.53 +                key.makeWeak();
    3.54              }
    3.55 -        } else {
    3.56 -            // merge with speculative values
    3.57 -            FileObject fo = key.fileObject;
    3.58 -            File f = FileUtil.toFile(fo);
    3.59 -            String absolutePath = f.getAbsolutePath();
    3.60 -            attributes = (Map) speculativeCache.get(absolutePath);
    3.61 -            boolean hadSpeculative = false;
    3.62 -            if (attributes == null) {
    3.63 -                attributes = new HashMap(5);
    3.64 -            } else {
    3.65 -                hadSpeculative = true;
    3.66 -            }
    3.67 -            if (value != null) {
    3.68 -                attributes.put(name, normalizeValue(value));
    3.69 -            } else {
    3.70 -                attributes.remove(name);
    3.71 -            }
    3.72 -            liveFileObjectsMap.put(key, attributes);
    3.73 -            if (hadSpeculative) {
    3.74 -                speculativeCache.remove(absolutePath);
    3.75 -                speculativePtr[0] = new HashMap(attributes);
    3.76 -            }
    3.77 -            key.makeWeak();
    3.78          }
    3.79  
    3.80      }
    3.81 @@ -146,21 +150,23 @@
    3.82          return value;
    3.83      }
    3.84  
    3.85 -    public static synchronized Object getImpl(FileObject fo, String name, Map[] speculativePtr) {
    3.86 -        Object key = new FileObjectKey(fo);
    3.87 -        Map attributes = (Map) liveFileObjectsMap.get(key);
    3.88 -        if (attributes != null) {
    3.89 -            return attributes.get(name);
    3.90 -        } else {
    3.91 -            // try speculative results
    3.92 -            File file = FileUtil.toFile(fo);
    3.93 -            String skey = file.getAbsolutePath();
    3.94 -            attributes = (Map) speculativeCache.get(skey);
    3.95 +    public static Object getImpl(FileObject fo, String name, Map[] speculativePtr) {
    3.96 +        File file = FileUtil.toFile(fo);
    3.97 +        synchronized (Memory.class) {
    3.98 +            Object key = new FileObjectKey(fo);
    3.99 +            Map attributes = (Map) liveFileObjectsMap.get(key);
   3.100              if (attributes != null) {
   3.101 -                liveFileObjectsMap.put(key, attributes);
   3.102 -                speculativeCache.remove(skey);
   3.103 -                speculativePtr[0] = new HashMap(attributes);
   3.104                  return attributes.get(name);
   3.105 +            } else {
   3.106 +                // try speculative results
   3.107 +                String skey = file.getAbsolutePath();
   3.108 +                attributes = (Map) speculativeCache.get(skey);
   3.109 +                if (attributes != null) {
   3.110 +                    liveFileObjectsMap.put(key, attributes);
   3.111 +                    speculativeCache.remove(skey);
   3.112 +                    speculativePtr[0] = new HashMap(attributes);
   3.113 +                    return attributes.get(name);
   3.114 +                }
   3.115              }
   3.116          }
   3.117          return null;
   3.118 @@ -187,20 +193,21 @@
   3.119       * Note that the entry can contain info that attribute
   3.120       * does not exist!
   3.121       */
   3.122 -    public static synchronized boolean existsEntry(FileObject fo, String name) {
   3.123 -        Object key = new FileObjectKey(fo);
   3.124 -        Map attributes = (Map) liveFileObjectsMap.get(key);
   3.125 -        if (attributes != null) {
   3.126 -            return attributes.keySet().contains(name);
   3.127 -        } else {
   3.128 -            File file = FileUtil.toFile(fo);
   3.129 -            key = file.getAbsolutePath();
   3.130 -            attributes = (Map) speculativeCache.get(key);
   3.131 +    public static boolean existsEntry(FileObject fo, String name) {
   3.132 +        File file = FileUtil.toFile(fo);
   3.133 +        synchronized (Memory.class) {
   3.134 +            Object key = new FileObjectKey(fo);
   3.135 +            Map attributes = (Map) liveFileObjectsMap.get(key);
   3.136              if (attributes != null) {
   3.137                  return attributes.keySet().contains(name);
   3.138 +            } else {
   3.139 +                key = file.getAbsolutePath();
   3.140 +                attributes = (Map) speculativeCache.get(key);
   3.141 +                if (attributes != null) {
   3.142 +                    return attributes.keySet().contains(name);
   3.143 +                }
   3.144              }
   3.145          }
   3.146 -
   3.147          return false;
   3.148      }
   3.149