diff options
author | Ben Becker <ben.becker@10gen.com> | 2012-06-10 18:51:57 -0700 |
---|---|---|
committer | Ben Becker <ben.becker@10gen.com> | 2012-06-10 18:51:57 -0700 |
commit | 9a5324a03581753b7c1e7a66959d3c60e7ed7a85 (patch) | |
tree | 5d35fe8c6039161f9e126352c03d49b61ebf08cf /src | |
parent | edbdfe32ce35e47b2fd11f7ca413353017f138c1 (diff) | |
download | mongo-9a5324a03581753b7c1e7a66959d3c60e7ed7a85.tar.gz |
SERVER-5819: fix file allocator on win32
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/util/file_allocator.cpp | 69 | ||||
-rw-r--r-- | src/mongo/util/file_allocator.h | 8 | ||||
-rw-r--r-- | src/mongo/util/mmap_win.cpp | 2 |
3 files changed, 51 insertions, 28 deletions
diff --git a/src/mongo/util/file_allocator.cpp b/src/mongo/util/file_allocator.cpp index 096d5518821..905029736bf 100644 --- a/src/mongo/util/file_allocator.cpp +++ b/src/mongo/util/file_allocator.cpp @@ -15,19 +15,19 @@ * limitations under the License. */ -#include "pch.h" - +#include "mongo/pch.h" +#include "mongo/util/file_allocator.h" +#include <boost/thread.hpp> +#include <boost/filesystem/operations.hpp> #include <fcntl.h> #include <errno.h> -#include <boost/thread.hpp> - #if defined(__freebsd__) || defined(__openbsd__) -#include <sys/stat.h> +# include <sys/stat.h> #endif #if defined(__linux__) -#include <sys/vfs.h> +# include <sys/vfs.h> #endif #if defined(_WIN32) @@ -37,19 +37,20 @@ #include "mongo/util/time_support.h" #include "mongo/util/timer.h" #include "mongo/util/mongoutils/str.h" +#include "mongo/util/paths.h" + using namespace mongoutils; #ifndef O_NOATIME #define O_NOATIME (0) #endif -#include "file_allocator.h" -#include "paths.h" - -#include <boost/filesystem/operations.hpp> - namespace mongo { + // unique number for temporary file names + unsigned long long FileAllocator::_uniqueNumber = 0; + static SimpleMutex _uniqueNumberMutex( "uniqueNumberMutex" ); + /** * Aliases for Win32 CRT functions */ @@ -228,11 +229,19 @@ namespace mongo { return false; } - string makeTempFileName( boost::filesystem::path root ) { + string FileAllocator::makeTempFileName( boost::filesystem::path root ) { while( 1 ) { boost::filesystem::path p = root / "_tmp"; stringstream ss; - ss << (unsigned) rand(); + unsigned long long thisUniqueNumber; + { + // increment temporary file name counter + // TODO: SERVER-6055 -- Unify temporary file name selection + SimpleMutex::scoped_lock lk(_uniqueNumberMutex); + thisUniqueNumber = _uniqueNumber; + ++_uniqueNumber; + } + ss << thisUniqueNumber; p /= ss.str(); string fn = p.string(); if( !boost::filesystem::exists(p) ) @@ -243,7 +252,12 @@ namespace mongo { void FileAllocator::run( FileAllocator * fa ) { setThreadName( "FileAllocator" ); - srand( static_cast <unsigned>( curTimeMicros() ) ); + { + // initialize unique temporary file name counter + // TODO: SERVER-6055 -- Unify temporary file name selection + SimpleMutex::scoped_lock lk(_uniqueNumberMutex); + _uniqueNumber = curTimeMicros64(); + } while( 1 ) { { scoped_lock lk( fa->_pendingMutex ); @@ -267,7 +281,7 @@ namespace mongo { log() << "allocating new datafile " << name << ", filling with zeroes..." << endl; boost::filesystem::path parent = ensureParentDirCreated(name); - tmp = makeTempFileName( parent ); + tmp = fa->makeTempFileName( parent ); ensureParentDirCreated(tmp); #if defined(_WIN32) @@ -296,9 +310,10 @@ namespace mongo { if( rename(tmp.c_str(), name.c_str()) ) { const string& errStr = errnoWithDescription(); - log() << "error: couldn't rename " << tmp - << " to " << name << ' ' << errStr << endl; - msgasserted(13653, ""); + const string& errMessage = str::stream() + << "error: couldn't rename " << tmp + << " to " << name << ' ' << errStr; + msgasserted(13653, errMessage); } flushMyDirectory(name); @@ -310,18 +325,18 @@ namespace mongo { // no longer in a failed state. allow new writers. fa->_failed = false; } - catch ( ... ) { - if ( fd > 0 ) - close( fd ); + catch ( const std::exception& e ) { log() << "error: failed to allocate new file: " << name - << " size: " << size << ' ' << errnoWithDescription() << warnings + << " size: " << size << ' ' << e.what() << ". will try again in 10 seconds" << endl; + if ( fd > 0 ) + close( fd ); try { - if ( tmp.size() ) - MONGO_ASSERT_ON_EXCEPTION( boost::filesystem::remove( tmp ) ); - MONGO_ASSERT_ON_EXCEPTION( boost::filesystem::remove( name ) ); - } - catch ( ... ) { + if ( ! tmp.empty() ) + boost::filesystem::remove( tmp ); + boost::filesystem::remove( name ); + } catch ( const std::exception& e ) { + log() << "error removing files: " << e.what() << endl; } scoped_lock lk( fa->_pendingMutex ); fa->_failed = true; diff --git a/src/mongo/util/file_allocator.h b/src/mongo/util/file_allocator.h index b51aa099084..e11ecc4f550 100644 --- a/src/mongo/util/file_allocator.h +++ b/src/mongo/util/file_allocator.h @@ -18,7 +18,7 @@ #include "pch.h" #include <list> - +#include <boost/filesystem/path.hpp> #include <boost/thread/condition.hpp> namespace mongo { @@ -75,12 +75,18 @@ namespace mongo { /** called from the worked thread */ static void run( FileAllocator * fa ); + // generate a unique name for temporary files + string makeTempFileName( boost::filesystem::path root ); + mutable mongo::mutex _pendingMutex; mutable boost::condition _pendingUpdated; std::list< string > _pending; mutable map< string, long > _pendingSize; + // unique number for temporary files + static unsigned long long _uniqueNumber; + bool _failed; static FileAllocator* _instance; diff --git a/src/mongo/util/mmap_win.cpp b/src/mongo/util/mmap_win.cpp index 330c29c6fce..8bc7097c144 100644 --- a/src/mongo/util/mmap_win.cpp +++ b/src/mongo/util/mmap_win.cpp @@ -23,6 +23,7 @@ #include "../db/memconcept.h" #include "mongo/util/timer.h" #include "mongo/util/concurrency/remap_lock.h" +#include "mongo/util/file_allocator.h" namespace mongo { @@ -135,6 +136,7 @@ namespace mongo { void* MemoryMappedFile::map(const char *filenameIn, unsigned long long &length, int options) { verify( fd == 0 && len == 0 ); // can't open more than once setFilename(filenameIn); + FileAllocator::get()->allocateAsap( filenameIn, length ); /* big hack here: Babble uses db names with colons. doesn't seem to work on windows. temporary perhaps. */ char filename[256]; strncpy(filename, filenameIn, 255); |