ClipRect RenderLayerClipper::backgroundClipRect(const ClipRectsContext& clipRectsContext) const { ASSERT(m_renderer.layer()->parent()); if (clipRectsContext.clipRectsType == CompositingClipRects) const_cast<RenderLayerClipper*>(this)->clearClipRectsIncludingDescendants(CompositingClipRects); ClipRects parentRects; // If we cross into a different pagination context, then we can't rely on the cache. // Just switch over to using TemporaryClipRects. if (clipRectsContext.clipRectsType != TemporaryClipRects && m_renderer.layer()->parent()->enclosingPaginationLayer() != m_renderer.layer()->enclosingPaginationLayer()) { ClipRectsContext tempContext(clipRectsContext); tempContext.clipRectsType = TemporaryClipRects; parentClipRects(tempContext, parentRects); } else { parentClipRects(clipRectsContext, parentRects); } ClipRect backgroundClipRect = backgroundClipRectForPosition(parentRects, m_renderer.style()->position()); RenderView* view = m_renderer.view(); ASSERT(view); // Note: infinite clipRects should not be scrolled here, otherwise they will accidentally no longer be considered infinite. if (parentRects.fixed() && clipRectsContext.rootLayer->renderer() == view && backgroundClipRect != PaintInfo::infiniteRect()) backgroundClipRect.move(view->frameView()->scrollOffsetForFixedPosition()); return backgroundClipRect; }
void RenderLayerClipper::updateClipRects(const ClipRectsContext& clipRectsContext) { ClipRectsType clipRectsType = clipRectsContext.clipRectsType; ASSERT(clipRectsType < NumCachedClipRectsTypes); if (m_clipRectsCache && clipRectsContext.rootLayer == m_clipRectsCache->clipRectsRoot(clipRectsType) && m_clipRectsCache->getClipRects(clipRectsType, clipRectsContext.respectOverflowClip)) { // FIXME: We used to ASSERT that we always got a consistent root layer. // We should add a test that has an inconsistent root. See // http://crbug.com/366118 for an example. ASSERT(m_clipRectsCache->m_scrollbarRelevancy[clipRectsType] == clipRectsContext.overlayScrollbarSizeRelevancy); #ifdef CHECK_CACHED_CLIP_RECTS // This code is useful to check cached clip rects, but is too expensive to leave enabled in debug builds by default. ClipRectsContext tempContext(clipRectsContext); tempContext.clipRectsType = TemporaryClipRects; ClipRects clipRects; calculateClipRects(tempContext, clipRects); ASSERT(clipRects == *m_clipRectsCache->getClipRects(clipRectsType, clipRectsContext.respectOverflowClip).get()); #endif return; // We have the correct cached value. } // For transformed layers, the root layer was shifted to be us, so there is no need to // examine the parent. We want to cache clip rects with us as the root. RenderLayer* parentLayer = !isClippingRootForContext(clipRectsContext) ? m_renderer.layer()->parent() : 0; if (parentLayer) parentLayer->clipper().updateClipRects(clipRectsContext); ClipRects clipRects; calculateClipRects(clipRectsContext, clipRects); if (!m_clipRectsCache) m_clipRectsCache = adoptPtr(new ClipRectsCache); if (parentLayer && parentLayer->clipper().clipRects(clipRectsContext) && clipRects == *parentLayer->clipper().clipRects(clipRectsContext)) m_clipRectsCache->setClipRects(clipRectsType, clipRectsContext.respectOverflowClip, parentLayer->clipper().clipRects(clipRectsContext), clipRectsContext.rootLayer); else m_clipRectsCache->setClipRects(clipRectsType, clipRectsContext.respectOverflowClip, ClipRects::create(clipRects), clipRectsContext.rootLayer); #ifndef NDEBUG m_clipRectsCache->m_scrollbarRelevancy[clipRectsType] = clipRectsContext.overlayScrollbarSizeRelevancy; #endif }
void RenderLayerClipper::updateClipRects(const ClipRectsContext& clipRectsContext) { ClipRectsType clipRectsType = clipRectsContext.clipRectsType; ASSERT(clipRectsType < NumCachedClipRectsTypes); if (m_clipRectsCache && m_clipRectsCache->getClipRects(clipRectsType, clipRectsContext.respectOverflowClip)) { // FIXME: these asserts trigger for squashing. Need to update this code to support squashing as appropriate. ASSERT(clipRectsContext.rootLayer == m_clipRectsCache->m_clipRectsRoot[clipRectsType]); ASSERT(m_clipRectsCache->m_scrollbarRelevancy[clipRectsType] == clipRectsContext.overlayScrollbarSizeRelevancy); #ifdef CHECK_CACHED_CLIP_RECTS // This code is useful to check cached clip rects, but is too expensive to leave enabled in debug builds by default. ClipRectsContext tempContext(clipRectsContext); tempContext.clipRectsType = TemporaryClipRects; ClipRects clipRects; calculateClipRects(tempContext, clipRects); ASSERT(clipRects == *m_clipRectsCache->getClipRects(clipRectsType, clipRectsContext.respectOverflowClip).get()); #endif return; // We have the correct cached value. } // For transformed layers, the root layer was shifted to be us, so there is no need to // examine the parent. We want to cache clip rects with us as the root. RenderLayer* parentLayer = clipRectsContext.rootLayer != m_renderer->layer() ? m_renderer->layer()->parent() : 0; if (parentLayer) parentLayer->clipper().updateClipRects(clipRectsContext); ClipRects clipRects; calculateClipRects(clipRectsContext, clipRects); if (!m_clipRectsCache) m_clipRectsCache = adoptPtr(new ClipRectsCache); if (parentLayer && parentLayer->clipper().clipRects(clipRectsContext) && clipRects == *parentLayer->clipper().clipRects(clipRectsContext)) m_clipRectsCache->setClipRects(clipRectsType, clipRectsContext.respectOverflowClip, parentLayer->clipper().clipRects(clipRectsContext)); else m_clipRectsCache->setClipRects(clipRectsType, clipRectsContext.respectOverflowClip, ClipRects::create(clipRects)); #ifndef NDEBUG m_clipRectsCache->m_clipRectsRoot[clipRectsType] = clipRectsContext.rootLayer; m_clipRectsCache->m_scrollbarRelevancy[clipRectsType] = clipRectsContext.overlayScrollbarSizeRelevancy; #endif }
ClipRects* PaintLayerClipper::clipRectsIfCached(const ClipRectsContext& context) const { ASSERT(context.usesCache()); if (!m_cache) return 0; ClipRectsCache::Entry& entry = m_cache->get(context.cacheSlot()); // FIXME: We used to ASSERT that we always got a consistent root layer. // We should add a test that has an inconsistent root. See // http://crbug.com/366118 for an example. if (context.rootLayer != entry.root) return 0; ASSERT(entry.scrollbarRelevancy == context.scrollbarRelevancy); #ifdef CHECK_CACHED_CLIP_RECTS // This code is useful to check cached clip rects, but is too expensive to leave enabled in debug builds by default. ClipRectsContext tempContext(context); tempContext.cacheSlot = UncachedClipRects; RefPtr<ClipRects> clipRects = ClipRects::create(); calculateClipRects(tempContext, *clipRects); ASSERT(clipRects == *entry.clipRects); #endif return entry.clipRects.get(); }
~RepairFileDeleter() { if ( _success ) return; log() << "cleaning up failed repair " << "db: " << _dbName << " path: " << _pathString; try { getDur().syncDataAndTruncateJournal(); MongoFile::flushAll(true); // need both in case journaling is disabled { Client::Context tempContext( _dbName, _pathString ); Database::closeDatabase( _dbName, _pathString ); } MONGO_ASSERT_ON_EXCEPTION( boost::filesystem::remove_all( _path ) ); } catch ( DBException& e ) { error() << "RepairFileDeleter failed to cleanup: " << e; error() << "aborting"; fassertFailed( 17402 ); } }
Context::Context(const Format &fmnt) : ContextSysBase() { mTarget = nullptr; mGLFormat = fmnt; init(); if ( mGLFormat.versionMajor >= 3 ) { // Use a "sppringboard" context used to create an // OpenGL 3.0 or greater context. Format tempFormat; tempFormat.versionMajor = 2; tempFormat.versionMinor = 1; tempFormat.versionProfile = Profile::COMPATIBILITY; Context tempContext(tempFormat); tempContext.makeCurrent(); initNewContext(); tempContext.doneCurrent(); } else { // Simply initialize an old context for our window. initOldContext(); } // GLEW initialization. makeCurrent(); { GLenum wglewInitResult = wglewInit(); GLenum glewInitResult = glewInit(); assert(GLEW_OK == wglewInitResult && GLEW_OK == glewInitResult); } doneCurrent(); }
Status MMAPV1Engine::repairDatabase( OperationContext* txn, const std::string& dbName, bool preserveClonedFilesOnFailure, bool backupOriginalFiles ) { // We must hold some form of lock here invariant(txn->lockState()->threadState()); invariant( dbName.find( '.' ) == string::npos ); scoped_ptr<RepairFileDeleter> repairFileDeleter; log() << "repairDatabase " << dbName << endl; BackgroundOperation::assertNoBgOpInProgForDb(dbName); txn->recoveryUnit()->syncDataAndTruncateJournal(); // Must be done before and after repair intmax_t totalSize = dbSize( dbName ); intmax_t freeSize = File::freeSpace(storageGlobalParams.repairpath); if ( freeSize > -1 && freeSize < totalSize ) { return Status( ErrorCodes::OutOfDiskSpace, str::stream() << "Cannot repair database " << dbName << " having size: " << totalSize << " (bytes) because free disk space is: " << freeSize << " (bytes)" ); } txn->checkForInterrupt(); Path reservedPath = uniqueReservedPath( ( preserveClonedFilesOnFailure || backupOriginalFiles ) ? "backup" : "_tmp" ); MONGO_ASSERT_ON_EXCEPTION( boost::filesystem::create_directory( reservedPath ) ); string reservedPathString = reservedPath.string(); if ( !preserveClonedFilesOnFailure ) repairFileDeleter.reset( new RepairFileDeleter( txn, dbName, reservedPathString, reservedPath ) ); { Database* originalDatabase = dbHolder().get(txn, dbName); if (originalDatabase == NULL) { return Status(ErrorCodes::NamespaceNotFound, "database does not exist to repair"); } scoped_ptr<MMAPV1DatabaseCatalogEntry> dbEntry; scoped_ptr<Database> tempDatabase; { dbEntry.reset( new MMAPV1DatabaseCatalogEntry( txn, dbName, reservedPathString, storageGlobalParams.directoryperdb, true ) ); invariant( !dbEntry->exists() ); tempDatabase.reset( new Database( txn, dbName, dbEntry.get() ) ); } map<string,CollectionOptions> namespacesToCopy; { string ns = dbName + ".system.namespaces"; Client::Context ctx(txn, ns ); Collection* coll = originalDatabase->getCollection( txn, ns ); if ( coll ) { scoped_ptr<RecordIterator> it( coll->getIterator( txn, DiskLoc(), false, CollectionScanParams::FORWARD ) ); while ( !it->isEOF() ) { DiskLoc loc = it->getNext(); BSONObj obj = coll->docFor( loc ); string ns = obj["name"].String(); NamespaceString nss( ns ); if ( nss.isSystem() ) { if ( nss.isSystemDotIndexes() ) continue; if ( nss.coll() == "system.namespaces" ) continue; } if ( !nss.isNormal() ) continue; CollectionOptions options; if ( obj["options"].isABSONObj() ) { Status status = options.parse( obj["options"].Obj() ); if ( !status.isOK() ) return status; } namespacesToCopy[ns] = options; } } } for ( map<string,CollectionOptions>::const_iterator i = namespacesToCopy.begin(); i != namespacesToCopy.end(); ++i ) { string ns = i->first; CollectionOptions options = i->second; Collection* tempCollection = NULL; { Client::Context tempContext(txn, ns, tempDatabase ); WriteUnitOfWork wunit(txn); tempCollection = tempDatabase->createCollection(txn, ns, options, true, false); wunit.commit(); } Client::Context readContext(txn, ns, originalDatabase); Collection* originalCollection = originalDatabase->getCollection( txn, ns ); invariant( originalCollection ); // data // TODO SERVER-14812 add a mode that drops duplicates rather than failing MultiIndexBlock indexer(txn, tempCollection ); { vector<BSONObj> indexes; IndexCatalog::IndexIterator ii = originalCollection->getIndexCatalog()->getIndexIterator( false ); while ( ii.more() ) { IndexDescriptor* desc = ii.next(); indexes.push_back( desc->infoObj() ); } Client::Context tempContext(txn, ns, tempDatabase); Status status = indexer.init( indexes ); if ( !status.isOK() ) return status; } scoped_ptr<RecordIterator> iterator( originalCollection->getIterator( txn, DiskLoc(), false, CollectionScanParams::FORWARD )); while ( !iterator->isEOF() ) { DiskLoc loc = iterator->getNext(); invariant( !loc.isNull() ); BSONObj doc = originalCollection->docFor( loc ); Client::Context tempContext(txn, ns, tempDatabase); WriteUnitOfWork wunit(txn); StatusWith<DiskLoc> result = tempCollection->insertDocument(txn, doc, &indexer, false); if ( !result.isOK() ) return result.getStatus(); wunit.commit(); txn->checkForInterrupt(false); } Status status = indexer.doneInserting(); if (!status.isOK()) return status; { Client::Context tempContext(txn, ns, tempDatabase); WriteUnitOfWork wunit(txn); indexer.commit(); wunit.commit(); } } txn->recoveryUnit()->syncDataAndTruncateJournal(); globalStorageEngine->flushAllFiles(true); // need both in case journaling is disabled txn->checkForInterrupt(false); } // at this point if we abort, we don't want to delete new files // as they might be the only copies if ( repairFileDeleter.get() ) repairFileDeleter->success(); dbHolder().close( txn, dbName ); if ( backupOriginalFiles ) { _renameForBackup( dbName, reservedPath ); } else { // first make new directory before deleting data Path newDir = Path(storageGlobalParams.dbpath) / dbName; MONGO_ASSERT_ON_EXCEPTION(boost::filesystem::create_directory(newDir)); // this deletes old files _deleteDataFiles( dbName ); if ( !boost::filesystem::exists(newDir) ) { // we deleted because of directoryperdb // re-create MONGO_ASSERT_ON_EXCEPTION(boost::filesystem::create_directory(newDir)); } } _replaceWithRecovered( dbName, reservedPathString.c_str() ); if ( !backupOriginalFiles ) MONGO_ASSERT_ON_EXCEPTION( boost::filesystem::remove_all( reservedPath ) ); return Status::OK(); }
Status repairDatabase( string dbName, bool preserveClonedFilesOnFailure, bool backupOriginalFiles ) { scoped_ptr<RepairFileDeleter> repairFileDeleter; doingRepair dr; dbName = nsToDatabase( dbName ); log() << "repairDatabase " << dbName << endl; invariant( cc().database()->name() == dbName ); invariant( cc().database()->path() == storageGlobalParams.dbpath ); BackgroundOperation::assertNoBgOpInProgForDb(dbName); getDur().syncDataAndTruncateJournal(); // Must be done before and after repair intmax_t totalSize = dbSize( dbName ); intmax_t freeSize = File::freeSpace(storageGlobalParams.repairpath); if ( freeSize > -1 && freeSize < totalSize ) { return Status( ErrorCodes::OutOfDiskSpace, str::stream() << "Cannot repair database " << dbName << " having size: " << totalSize << " (bytes) because free disk space is: " << freeSize << " (bytes)" ); } killCurrentOp.checkForInterrupt(); Path reservedPath = uniqueReservedPath( ( preserveClonedFilesOnFailure || backupOriginalFiles ) ? "backup" : "_tmp" ); MONGO_ASSERT_ON_EXCEPTION( boost::filesystem::create_directory( reservedPath ) ); string reservedPathString = reservedPath.string(); if ( !preserveClonedFilesOnFailure ) repairFileDeleter.reset( new RepairFileDeleter( dbName, reservedPathString, reservedPath ) ); { Database* originalDatabase = dbHolder().get( dbName, storageGlobalParams.dbpath ); if ( originalDatabase == NULL ) return Status( ErrorCodes::NamespaceNotFound, "database does not exist to repair" ); Database* tempDatabase = NULL; { bool justCreated = false; tempDatabase = dbHolderW().getOrCreate( dbName, reservedPathString, justCreated ); invariant( justCreated ); } map<string,CollectionOptions> namespacesToCopy; { string ns = dbName + ".system.namespaces"; Client::Context ctx( ns ); Collection* coll = originalDatabase->getCollection( ns ); if ( coll ) { scoped_ptr<CollectionIterator> it( coll->getIterator( DiskLoc(), false, CollectionScanParams::FORWARD ) ); while ( !it->isEOF() ) { DiskLoc loc = it->getNext(); BSONObj obj = coll->docFor( loc ); string ns = obj["name"].String(); NamespaceString nss( ns ); if ( nss.isSystem() ) { if ( nss.isSystemDotIndexes() ) continue; if ( nss.coll() == "system.namespaces" ) continue; } if ( !nss.isNormal() ) continue; CollectionOptions options; if ( obj["options"].isABSONObj() ) { Status status = options.parse( obj["options"].Obj() ); if ( !status.isOK() ) return status; } namespacesToCopy[ns] = options; } } } for ( map<string,CollectionOptions>::const_iterator i = namespacesToCopy.begin(); i != namespacesToCopy.end(); ++i ) { string ns = i->first; CollectionOptions options = i->second; Collection* tempCollection = NULL; { Client::Context tempContext( ns, tempDatabase ); tempCollection = tempDatabase->createCollection( ns, options, true, false ); } Client::Context readContext( ns, originalDatabase ); Collection* originalCollection = originalDatabase->getCollection( ns ); invariant( originalCollection ); // data MultiIndexBlock indexBlock( tempCollection ); { vector<BSONObj> indexes; IndexCatalog::IndexIterator ii = originalCollection->getIndexCatalog()->getIndexIterator( false ); while ( ii.more() ) { IndexDescriptor* desc = ii.next(); indexes.push_back( desc->infoObj() ); } Client::Context tempContext( ns, tempDatabase ); Status status = indexBlock.init( indexes ); if ( !status.isOK() ) return status; } scoped_ptr<CollectionIterator> iterator( originalCollection->getIterator( DiskLoc(), false, CollectionScanParams::FORWARD ) ); while ( !iterator->isEOF() ) { DiskLoc loc = iterator->getNext(); invariant( !loc.isNull() ); BSONObj doc = originalCollection->docFor( loc ); Client::Context tempContext( ns, tempDatabase ); StatusWith<DiskLoc> result = tempCollection->insertDocument( doc, indexBlock ); if ( !result.isOK() ) return result.getStatus(); getDur().commitIfNeeded(); killCurrentOp.checkForInterrupt(false); } { Client::Context tempContext( ns, tempDatabase ); Status status = indexBlock.commit(); if ( !status.isOK() ) return status; } } getDur().syncDataAndTruncateJournal(); MongoFile::flushAll(true); // need both in case journaling is disabled killCurrentOp.checkForInterrupt(false); Client::Context tempContext( dbName, reservedPathString ); Database::closeDatabase( dbName, reservedPathString ); } // at this point if we abort, we don't want to delete new files // as they might be the only copies if ( repairFileDeleter.get() ) repairFileDeleter->success(); Client::Context ctx( dbName ); Database::closeDatabase(dbName, storageGlobalParams.dbpath); if ( backupOriginalFiles ) { _renameForBackup( dbName, reservedPath ); } else { // first make new directory before deleting data Path newDir = Path(storageGlobalParams.dbpath) / dbName; MONGO_ASSERT_ON_EXCEPTION(boost::filesystem::create_directory(newDir)); // this deletes old files _deleteDataFiles( dbName ); if ( !boost::filesystem::exists(newDir) ) { // we deleted because of directoryperdb // re-create MONGO_ASSERT_ON_EXCEPTION(boost::filesystem::create_directory(newDir)); } } _replaceWithRecovered( dbName, reservedPathString.c_str() ); if ( !backupOriginalFiles ) MONGO_ASSERT_ON_EXCEPTION( boost::filesystem::remove_all( reservedPath ) ); return Status::OK(); }