// **************************************************************************** // *** FileReferenceImpl // **************************************************************************** FileReferenceImpl::FileReferenceImpl(geFilePool &pool_, const std::string &fname_, int openFlags_, int createMask_) : pool(pool_), fname(fname_), reservation(), operationPending(false), closeError(0), openFlags(openFlags_), createMask(createMask_), cachedFilesize(0) { // run when pool.mutex IS locked if (!IsWriter()) { time_t mtime; if (!khGetFileInfo(fname, cachedFilesize, mtime)) { throw khSimpleException("No such file ") << fname; } } pool.filerefs.Add(fname, this); }
CCachedDirectory * CSVNStatusCache::GetDirectoryCacheEntry(const CTSVNPath& path) { ATLASSERT(path.IsDirectory() || !PathFileExists(path.GetWinPath())); CCachedDirectory::ItDir itMap; itMap = m_directoryCache.find(path); if ((itMap != m_directoryCache.end())&&(itMap->second)) { // We've found this directory in the cache return itMap->second; } else { // if the CCachedDirectory is NULL but the path is in our cache, // that means that path got invalidated and needs to be treated // as if it never was in our cache. So we remove the last remains // from the cache and start from scratch. AssertLock(); if (!IsWriter()) { // upgrading our state to writer Done(); WaitToWrite(); } // Since above there's a small chance that before we can upgrade to // writer state some other thread gained writer state and changed // the data, we have to recreate the iterator here again. itMap = m_directoryCache.find(path); if (itMap!=m_directoryCache.end()) { delete itMap->second; itMap->second = NULL; m_directoryCache.erase(itMap); } // We don't know anything about this directory yet - lets add it to our cache // but only if it exists! if (path.Exists() && m_shellCache.IsPathAllowed(path.GetWinPath()) && !g_SVNAdminDir.IsAdminDirPath(path.GetWinPath())) { // some notifications are for files which got removed/moved around. // In such cases, the CTSVNPath::IsDirectory() will return true (it assumes a directory if // the path doesn't exist). Which means we can get here with a path to a file // instead of a directory. // Since we're here most likely called from the crawler thread, the file could exist // again. If that's the case, just do nothing if (path.IsDirectory()||(!path.Exists())) { std::auto_ptr<CCachedDirectory> newcdir (new CCachedDirectory (path)); if (newcdir.get()) { itMap = m_directoryCache.lower_bound (path); ASSERT ( (itMap == m_directoryCache.end()) || (itMap->path != path)); itMap = m_directoryCache.insert (itMap, std::make_pair (path, newcdir.release())); if (!path.IsEmpty() && path.HasAdminDir()) CSVNStatusCache::Instance().AddFolderForCrawling(path); return itMap->second; } m_bClearMemory = true; } } return NULL; } }
CCachedDirectory * CGitStatusCache::GetDirectoryCacheEntry(const CTGitPath& path, bool isAddToWatch) { ATLASSERT(path.IsDirectory() || !PathFileExists(path.GetWinPath())); CCachedDirectory::ItDir itMap; itMap = m_directoryCache.find(path); if ((itMap != m_directoryCache.end())&&(itMap->second)) { // We've found this directory in the cache return itMap->second; } else { // if the CCachedDirectory is NULL but the path is in our cache, // that means that path got invalidated and needs to be treated // as if it never was in our cache. So we remove the last remains // from the cache and start from scratch. AssertLock(); if (!IsWriter()) { // upgrading our state to writer ATLTRACE("trying to upgrade the state to \"Writer\"\n"); Done(); ATLTRACE("Returned \"Reader\" state\n"); WaitToWrite(); ATLTRACE("Got \"Writer\" state now\n"); } // Since above there's a small chance that before we can upgrade to // writer state some other thread gained writer state and changed // the data, we have to recreate the iterator here again. itMap = m_directoryCache.find(path); if (itMap!=m_directoryCache.end()) m_directoryCache.erase(itMap); // We don't know anything about this directory yet - lets add it to our cache // but only if it exists! if (path.Exists() && m_shellCache.IsPathAllowed(path.GetWinPath()) && !g_GitAdminDir.IsAdminDirPath(path.GetWinPath())) { // some notifications are for files which got removed/moved around. // In such cases, the CTGitPath::IsDirectory() will return true (it assumes a directory if // the path doesn't exist). Which means we can get here with a path to a file // instead of a directory. // Since we're here most likely called from the crawler thread, the file could exist // again. If that's the case, just do nothing if (path.IsDirectory()||(!path.Exists())) { ATLTRACE(_T("adding %s to our cache\n"), path.GetWinPath()); CCachedDirectory * newcdir = new CCachedDirectory(path); if (newcdir) { CCachedDirectory * cdir = m_directoryCache.insert(m_directoryCache.lower_bound(path), std::make_pair(path, newcdir))->second; CString gitdir; if ((!path.IsEmpty())&&(path.HasAdminDir(&gitdir))&&isAddToWatch) { bool isVersion = true; CString subpaths; if(subpaths.GetLength() > gitdir.GetLength()) { if(subpaths[gitdir.GetLength()] == _T('\\')) subpaths=subpaths.Right(subpaths.GetLength() - gitdir.GetLength()-1); else subpaths=subpaths.Right(subpaths.GetLength() - gitdir.GetLength()); } CGitStatusCache::Instance().m_GitStatus.IsUnderVersionControl(gitdir, subpaths, true, &isVersion); /* Just watch version path */ if(isVersion) { watcher.AddPath(gitdir); watcher.AddPath(path); } } return cdir; } m_bClearMemory = true; } } return NULL; } }