Get rid of flawed Windows stat cache. b=456603 r=smichaud sr=dougt
☠☠ backed out by 413ed1ac017c ☠ ☠
authorJosh Aas <joshmoz@gmail.com>
Tue, 07 Oct 2008 23:18:05 -0400
changeset 20127 4a461b03f6ae91f4dd6af9492de0b90c86934f77
parent 20126 cf62923208e19b9458dae1d5805afa0b3cd162ce
child 20128 f9bbc6e85b6e2e7ebb6cb3f5953c82cf2d849341
child 20130 413ed1ac017c9b3038b1bfe0d1f1c702b01c37f1
push idunknown
push userunknown
push dateunknown
reviewerssmichaud, dougt
bugs456603
milestone1.9.1b2pre
Get rid of flawed Windows stat cache. b=456603 r=smichaud sr=dougt
xpcom/io/nsLocalFileWin.cpp
xpcom/io/nsLocalFileWin.h
--- a/xpcom/io/nsLocalFileWin.cpp
+++ b/xpcom/io/nsLocalFileWin.cpp
@@ -713,18 +713,17 @@ class nsDirEnumerator : public nsISimple
 NS_IMPL_ISUPPORTS2(nsDirEnumerator, nsISimpleEnumerator, nsIDirectoryEnumerator)
 
 
 //-----------------------------------------------------------------------------
 // nsLocalFile <public>
 //-----------------------------------------------------------------------------
 
 nsLocalFile::nsLocalFile()
-  : mDirty(PR_TRUE)
-  , mFollowSymlinks(PR_FALSE)
+  : mFollowSymlinks(PR_FALSE)
 {
 }
 
 NS_METHOD
 nsLocalFile::nsLocalFileConstructor(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr)
 {
     NS_ENSURE_ARG_POINTER(aInstancePtr);
     NS_ENSURE_NO_AGGREGATION(outer);
@@ -754,18 +753,17 @@ NS_IMPL_THREADSAFE_ISUPPORTS4(nsLocalFil
                               nsIHashable)
 
 
 //-----------------------------------------------------------------------------
 // nsLocalFile <private>
 //-----------------------------------------------------------------------------
 
 nsLocalFile::nsLocalFile(const nsLocalFile& other)
-  : mDirty(PR_TRUE)
-  , mFollowSymlinks(other.mFollowSymlinks)
+  : mFollowSymlinks(other.mFollowSymlinks)
   , mWorkingPath(other.mWorkingPath)
 {
 }
 
 // Resolve the shortcut file from mWorkingPath and write the path 
 // it points to into mResolvedPath.
 nsresult
 nsLocalFile::ResolveShortcut()
@@ -793,20 +791,16 @@ nsLocalFile::ResolveShortcut()
 #endif
 }
 
 // Resolve any shortcuts and stat the resolved path. After a successful return
 // the path is guaranteed valid and the members of mFileInfo64 can be used.
 nsresult
 nsLocalFile::ResolveAndStat()
 {
-    // if we aren't dirty then we are already done
-    if (!mDirty)
-        return NS_OK;
-
     // we can't resolve/stat anything that isn't a valid NSPR addressable path
     if (mWorkingPath.IsEmpty())
         return NS_ERROR_FILE_INVALID_PATH;
 
     // this is usually correct
     mResolvedPath.Assign(mWorkingPath);
 
     // slutty hack designed to work around bug 134796 until it is fixed
@@ -819,17 +813,16 @@ nsLocalFile::ResolveAndStat()
     if (NS_FAILED(GetFileInfo(nsprPath, &mFileInfo64)))
         return NS_ERROR_FILE_NOT_FOUND;
 
     // if this isn't a shortcut file or we aren't following symlinks then we're done 
     if (!mFollowSymlinks 
         || mFileInfo64.type != PR_FILE_FILE 
         || !IsShortcutPath(mWorkingPath))
     {
-        mDirty = PR_FALSE;
         return NS_OK;
     }
 
     // we need to resolve this shortcut to what it points to, this will
     // set mResolvedPath. Even if it fails we need to have the resolved
     // path equal to working path for those functions that always use
     // the resolved path.
     nsresult rv = ResolveShortcut();
@@ -838,17 +831,16 @@ nsLocalFile::ResolveAndStat()
         mResolvedPath.Assign(mWorkingPath);
         return rv;
     }
 
     // get the details of the resolved path
     if (NS_FAILED(GetFileInfo(mResolvedPath, &mFileInfo64)))
         return NS_ERROR_FILE_NOT_FOUND;
 
-    mDirty = PR_FALSE;
     return NS_OK;
 }
 
 
 //-----------------------------------------------------------------------------
 // nsLocalFile::nsIFile,nsILocalFile
 //-----------------------------------------------------------------------------
 
@@ -875,18 +867,16 @@ nsLocalFile::InitWithFile(nsILocalFile *
     if (path.IsEmpty())
         return NS_ERROR_INVALID_ARG;
     return InitWithPath(path); 
 }
 
 NS_IMETHODIMP
 nsLocalFile::InitWithPath(const nsAString &filePath)
 {
-    MakeDirty();
-
     nsAString::const_iterator begin, end;
     filePath.BeginReading(begin);
     filePath.EndReading(end);
 
     // input string must not be empty
     if (begin == end)
         return NS_ERROR_FAILURE;
 
@@ -1095,18 +1085,16 @@ nsLocalFile::AppendInternal(const nsAFla
         // catches the remaining cases of prefixes 
         if (StringBeginsWith(node, NS_LITERAL_STRING("..\\")))
             return NS_ERROR_FILE_UNRECOGNIZED_PATH;
     }
     // single components can't contain '\'
     else if (node.FindChar(L'\\') != kNotFound)
         return NS_ERROR_FILE_UNRECOGNIZED_PATH;
 #endif
-
-    MakeDirty();
     
     mWorkingPath.Append(NS_LITERAL_STRING("\\") + node);
     
     return NS_OK;
 }
 
 #define TOUPPER(u) (((u) >= L'a' && (u) <= L'z') ? \
                     (u) - (L'a' - L'A') : (u))
@@ -1260,17 +1248,16 @@ nsLocalFile::Normalize()
     // kill trailing dots and spaces.
     PRInt32 filePathLen = mWorkingPath.Length() - 1;
     while(filePathLen > 0 && (mWorkingPath[filePathLen] == L' ' ||
           mWorkingPath[filePathLen] == L'.'))
     {
         mWorkingPath.Truncate(filePathLen--);
     } 
 
-    MakeDirty();
 #else // WINCE
     // WINCE FIX
 #endif 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsLocalFile::GetLeafName(nsAString &aLeafName)
@@ -1289,18 +1276,16 @@ nsLocalFile::GetLeafName(nsAString &aLea
         aLeafName = Substring(mWorkingPath, offset + 1);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsLocalFile::SetLeafName(const nsAString &aLeafName)
 {
-    MakeDirty();
-
     if(mWorkingPath.IsEmpty())
         return NS_ERROR_FILE_UNRECOGNIZED_PATH;
 
     // cannot use nsCString::RFindChar() due to 0x5c problem
     PRInt32 offset = mWorkingPath.RFindChar(L'\\');
     if (offset)
     {
         mWorkingPath.Truncate(offset+1);
@@ -1675,18 +1660,16 @@ nsLocalFile::CopyMove(nsIFile *aParentDi
           NS_ENSURE_SUCCESS(rv,rv);
         }
     }
 
 
     // If we moved, we want to adjust this.
     if (move)
     {
-        MakeDirty();
-
         nsAutoString newParentPath;
         newParentDir->GetPath(newParentPath);
 
         if (newParentPath.IsEmpty())
             return NS_ERROR_FAILURE;
 
         if (newName.IsEmpty())
         {
@@ -1830,17 +1813,16 @@ nsLocalFile::Remove(PRBool recursive)
     {
         rv = _wremove(mWorkingPath.get());
     }
 
     // fixup error code if necessary...
     if (rv == (nsresult)-1)
         rv = NSRESULT_FOR_ERRNO();
     
-    MakeDirty();
     return rv;
 }
 
 NS_IMETHODIMP
 nsLocalFile::GetLastModifiedTime(PRInt64 *aLastModifiedTime)
 {
     // Check we are correctly initialized.
     CHECK_mWorkingPath();
@@ -1899,34 +1881,27 @@ nsLocalFile::SetLastModifiedTime(PRInt64
         return rv;
 
     // set the modified time of the target as determined by mFollowSymlinks
     // If PR_TRUE, then this will be for the target of the shortcut file, 
     // otherwise it will be for the shortcut file itself (i.e. the same 
     // results as SetLastModifiedTimeOfLink)
 
     rv = SetModDate(aLastModifiedTime, mResolvedPath.get());
-    if (NS_SUCCEEDED(rv))
-        MakeDirty();
 
     return rv;
 }
 
 
 NS_IMETHODIMP
 nsLocalFile::SetLastModifiedTimeOfLink(PRInt64 aLastModifiedTime)
 {
     // The caller is assumed to have already called IsSymlink 
     // and to have found that this file is a link. 
-
-    nsresult rv = SetModDate(aLastModifiedTime, mWorkingPath.get());
-    if (NS_SUCCEEDED(rv))
-        MakeDirty();
-
-    return rv;
+    return SetModDate(aLastModifiedTime, mWorkingPath.get());
 }
 
 nsresult
 nsLocalFile::SetModDate(PRInt64 aLastModifiedTime, const PRUnichar *filePath)
 {
     HANDLE file = ::CreateFileW(filePath,          // pointer to name of the file
                                 GENERIC_WRITE,     // access (write) mode
                                 0,                 // share mode
@@ -2112,29 +2087,24 @@ nsLocalFile::SetFileSize(PRInt64 aFileSi
     HANDLE hFile = ::CreateFileW(mResolvedPath.get(),// pointer to name of the file
                                  GENERIC_WRITE,      // access (write) mode
                                  FILE_SHARE_READ,    // share mode
                                  NULL,               // pointer to security attributes
                                  OPEN_EXISTING,          // how to create
                                  FILE_ATTRIBUTE_NORMAL,  // file attributes
                                  NULL);
     if (hFile == INVALID_HANDLE_VALUE)
-    {
         return ConvertWinError(GetLastError());
-    }
 
     // seek the file pointer to the new, desired end of file
     // and then truncate the file at that position
     rv = NS_ERROR_FAILURE;
     aFileSize = MyFileSeek64(hFile, aFileSize, FILE_BEGIN);
     if (aFileSize != -1 && SetEndOfFile(hFile))
-    {
-        MakeDirty();
         rv = NS_OK;
-    }
 
     CloseHandle(hFile);
     return rv;
 }
 
 NS_IMETHODIMP
 nsLocalFile::GetDiskSpaceAvailable(PRInt64 *aDiskSpaceAvailable)
 {
@@ -2208,17 +2178,16 @@ NS_IMETHODIMP
 nsLocalFile::Exists(PRBool *_retval)
 {
     // Check we are correctly initialized.
     CHECK_mWorkingPath();
 
     NS_ENSURE_ARG(_retval);
     *_retval = PR_FALSE;
 
-    MakeDirty();
     nsresult rv = ResolveAndStat();
     *_retval = NS_SUCCEEDED(rv);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsLocalFile::IsWritable(PRBool *aIsWritable)
@@ -2562,17 +2531,16 @@ NS_IMETHODIMP
 nsLocalFile::GetFollowLinks(PRBool *aFollowLinks)
 {
     *aFollowLinks = mFollowSymlinks;
     return NS_OK;
 }
 NS_IMETHODIMP
 nsLocalFile::SetFollowLinks(PRBool aFollowLinks)
 {
-    MakeDirty();
     mFollowSymlinks = aFollowLinks;
     return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsLocalFile::GetDirectoryEntries(nsISimpleEnumerator * *entries)
 {
--- a/xpcom/io/nsLocalFileWin.h
+++ b/xpcom/io/nsLocalFileWin.h
@@ -47,23 +47,16 @@
 #include "nsCRT.h"
 #include "nsIFile.h"
 #include "nsIFactory.h"
 #include "nsILocalFileWin.h"
 #include "nsIHashable.h"
 #include "nsIClassInfoImpl.h"
 
 #include "windows.h"
-
-// For older version (<6.0) of the VC Compiler
-#if (_MSC_VER == 1100)
-#include <objbase.h>
-DEFINE_OLEGUID(IID_IPersistFile, 0x0000010BL, 0, 0);
-#endif
-
 #include "shlobj.h"
 
 #include <sys/stat.h>
 
 class nsLocalFile : public nsILocalFileWin,
                     public nsIHashable
 {
 public:
@@ -91,34 +84,32 @@ public:
 public:
     static void GlobalInit();
     static void GlobalShutdown();
 
 private:
     nsLocalFile(const nsLocalFile& other);
     ~nsLocalFile() {}
 
-    PRPackedBool mDirty;            // cached information can only be used when this is PR_FALSE
     PRPackedBool mFollowSymlinks;   // should we follow symlinks when working on this file
     
     // this string will always be in native format!
     nsString mWorkingPath;
     
     // this will be the resolved path of shortcuts, it will *NEVER* 
     // be returned to the user
     nsString mResolvedPath;
 
     // this string, if not empty, is the *short* pathname that represents
     // mWorkingPath
     nsString mShortWorkingPath;
 
+    // call ResolveAndStat() whenever this needs to be up-to-date
     PRFileInfo64 mFileInfo64;
 
-    void MakeDirty() { mDirty = PR_TRUE; mShortWorkingPath.Truncate(); }
-
     nsresult ResolveAndStat();
     nsresult ResolveShortcut();
 
     void EnsureShortPath();
     
     nsresult CopyMove(nsIFile *newParentDir, const nsAString &newName,
                       PRBool followSymlinks, PRBool move);
     nsresult CopySingleFile(nsIFile *source, nsIFile* dest,