summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBen Becker <ben.becker@10gen.com>2012-06-10 18:51:57 -0700
committerBen Becker <ben.becker@10gen.com>2012-06-10 18:51:57 -0700
commit9a5324a03581753b7c1e7a66959d3c60e7ed7a85 (patch)
tree5d35fe8c6039161f9e126352c03d49b61ebf08cf /src
parentedbdfe32ce35e47b2fd11f7ca413353017f138c1 (diff)
downloadmongo-9a5324a03581753b7c1e7a66959d3c60e7ed7a85.tar.gz
SERVER-5819: fix file allocator on win32
Diffstat (limited to 'src')
-rw-r--r--src/mongo/util/file_allocator.cpp69
-rw-r--r--src/mongo/util/file_allocator.h8
-rw-r--r--src/mongo/util/mmap_win.cpp2
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);