// ****************************************************************************
// ***  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);
}
Beispiel #2
0
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;
    }
}