2009-01-29 23:22:59 +01:00
|
|
|
// mmap_win.cpp
|
|
|
|
|
2009-10-27 20:58:27 +01:00
|
|
|
/* Copyright 2009 10gen Inc.
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
2009-01-29 23:22:59 +01:00
|
|
|
|
2010-04-27 21:27:52 +02:00
|
|
|
#include "pch.h"
|
2009-01-29 23:22:59 +01:00
|
|
|
#include "mmap.h"
|
2009-07-27 19:50:25 +02:00
|
|
|
#include <windows.h>
|
2009-01-30 00:38:35 +01:00
|
|
|
|
2009-01-29 23:22:59 +01:00
|
|
|
namespace mongo {
|
|
|
|
|
|
|
|
MemoryMappedFile::MemoryMappedFile() {
|
|
|
|
fd = 0;
|
|
|
|
maphandle = 0;
|
|
|
|
view = 0;
|
2010-01-15 21:31:51 +01:00
|
|
|
len = 0;
|
2009-01-29 23:22:59 +01:00
|
|
|
created();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MemoryMappedFile::close() {
|
|
|
|
if ( view )
|
|
|
|
UnmapViewOfFile(view);
|
|
|
|
view = 0;
|
|
|
|
if ( maphandle )
|
|
|
|
CloseHandle(maphandle);
|
|
|
|
maphandle = 0;
|
|
|
|
if ( fd )
|
|
|
|
CloseHandle(fd);
|
|
|
|
fd = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::wstring toWideString(const char *s) {
|
|
|
|
std::basic_ostringstream<TCHAR> buf;
|
|
|
|
buf << s;
|
|
|
|
return buf.str();
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned mapped = 0;
|
|
|
|
|
2010-02-04 23:17:09 +01:00
|
|
|
void* MemoryMappedFile::map(const char *_filename, long &length, int options) {
|
2009-02-11 17:28:49 +01:00
|
|
|
/* big hack here: Babble uses db names with colons. doesn't seem to work on windows. temporary perhaps. */
|
|
|
|
char filename[256];
|
|
|
|
strncpy(filename, _filename, 255);
|
|
|
|
filename[255] = 0;
|
|
|
|
{
|
2009-03-19 13:36:24 +01:00
|
|
|
size_t len = strlen( filename );
|
|
|
|
for ( size_t i=len-1; i>=0; i-- ){
|
|
|
|
if ( filename[i] == '/' ||
|
|
|
|
filename[i] == '\\' )
|
|
|
|
break;
|
|
|
|
|
|
|
|
if ( filename[i] == ':' )
|
|
|
|
filename[i] = '_';
|
2009-02-11 17:28:49 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-01-29 23:22:59 +01:00
|
|
|
updateLength( filename, length );
|
|
|
|
std::wstring filenamew = toWideString(filename);
|
|
|
|
|
2010-02-04 23:12:14 +01:00
|
|
|
DWORD createOptions = FILE_ATTRIBUTE_NORMAL;
|
|
|
|
if ( options & SEQUENTIAL )
|
|
|
|
createOptions |= FILE_FLAG_SEQUENTIAL_SCAN;
|
|
|
|
|
2009-01-29 23:22:59 +01:00
|
|
|
fd = CreateFile(
|
|
|
|
filenamew.c_str(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ,
|
2010-02-04 23:12:14 +01:00
|
|
|
NULL, OPEN_ALWAYS, createOptions , NULL);
|
2009-01-29 23:22:59 +01:00
|
|
|
if ( fd == INVALID_HANDLE_VALUE ) {
|
2009-10-27 19:25:45 +01:00
|
|
|
out() << "Create/OpenFile failed " << filename << ' ' << GetLastError() << endl;
|
2009-01-29 23:22:59 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
mapped += length;
|
|
|
|
|
|
|
|
maphandle = CreateFileMapping(fd, NULL, PAGE_READWRITE, 0, length, NULL);
|
|
|
|
if ( maphandle == NULL ) {
|
2009-10-27 19:25:45 +01:00
|
|
|
out() << "CreateFileMapping failed " << filename << ' ' << GetLastError() << endl;
|
2009-01-29 23:22:59 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
view = MapViewOfFile(maphandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
|
|
|
|
if ( view == 0 ) {
|
2010-04-24 20:03:14 +02:00
|
|
|
out() << "MapViewOfFile failed " << filename << " " << errnoWithDescription() << " ";
|
2009-01-29 23:22:59 +01:00
|
|
|
out() << GetLastError();
|
|
|
|
out() << endl;
|
|
|
|
}
|
2009-10-27 19:25:45 +01:00
|
|
|
len = length;
|
2009-01-29 23:22:59 +01:00
|
|
|
return view;
|
|
|
|
}
|
|
|
|
|
2010-03-10 03:46:47 +01:00
|
|
|
void MemoryMappedFile::flush(bool sync) {
|
2010-03-15 18:57:13 +01:00
|
|
|
uassert(13056, "Async flushing not supported on windows", sync);
|
|
|
|
|
2010-03-15 18:59:26 +01:00
|
|
|
if (!view || !fd) return;
|
2010-03-10 03:46:47 +01:00
|
|
|
|
|
|
|
bool success = FlushViewOfFile(view, 0); // 0 means whole mapping
|
|
|
|
if (!success){
|
|
|
|
int err = GetLastError();
|
2010-03-15 18:57:13 +01:00
|
|
|
out() << "FlushViewOfFile failed " << err << endl;
|
2010-03-10 03:46:47 +01:00
|
|
|
}
|
2009-01-29 23:22:59 +01:00
|
|
|
|
2010-03-15 18:57:13 +01:00
|
|
|
success = FlushFileBuffers(fd);
|
|
|
|
if (!success){
|
|
|
|
int err = GetLastError();
|
|
|
|
out() << "FlushFileBuffers failed " << err << endl;
|
2010-03-10 03:46:47 +01:00
|
|
|
}
|
|
|
|
}
|
2009-01-29 23:22:59 +01:00
|
|
|
}
|