summaryrefslogtreecommitdiff
path: root/util/mmap_posix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'util/mmap_posix.cpp')
-rw-r--r--util/mmap_posix.cpp94
1 files changed, 94 insertions, 0 deletions
diff --git a/util/mmap_posix.cpp b/util/mmap_posix.cpp
new file mode 100644
index 0000000..1237220
--- /dev/null
+++ b/util/mmap_posix.cpp
@@ -0,0 +1,94 @@
+// mmap_posix.cpp
+
+/* 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.
+ */
+
+#include "stdafx.h"
+#include "mmap.h"
+#include "file_allocator.h"
+
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+namespace mongo {
+
+ MemoryMappedFile::MemoryMappedFile() {
+ fd = 0;
+ maphandle = 0;
+ view = 0;
+ len = 0;
+ created();
+ }
+
+ void MemoryMappedFile::close() {
+ if ( view )
+ munmap(view, len);
+ view = 0;
+
+ if ( fd )
+ ::close(fd);
+ fd = 0;
+ }
+
+#ifndef O_NOATIME
+#define O_NOATIME 0
+#endif
+
+ void* MemoryMappedFile::map(const char *filename, long &length) {
+ // length may be updated by callee.
+ theFileAllocator().allocateAsap( filename, length );
+ len = length;
+
+ massert( 10446 , (string)"mmap() can't map area of size 0 [" + filename + "]" , length > 0 );
+
+
+ fd = open(filename, O_RDWR | O_NOATIME);
+ if ( fd <= 0 ) {
+ out() << "couldn't open " << filename << ' ' << OUTPUT_ERRNO << endl;
+ return 0;
+ }
+
+ off_t filelen = lseek(fd, 0, SEEK_END);
+ if ( filelen != length ){
+ cout << "wanted length: " << length << " filelen: " << filelen << endl;
+ cout << sizeof(size_t) << endl;
+ massert( 10447 , "file size allocation failed", filelen == length );
+ }
+ lseek( fd, 0, SEEK_SET );
+
+ view = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ if ( view == MAP_FAILED ) {
+ out() << " mmap() failed for " << filename << " len:" << length << " " << OUTPUT_ERRNO << endl;
+ if ( errno == ENOMEM ){
+ out() << " mmap failed with out of memory, if you're using 32-bits, then you probably need to upgrade to 64" << endl;
+ }
+ return 0;
+ }
+ return view;
+ }
+
+ void MemoryMappedFile::flush(bool sync) {
+ if ( view == 0 || fd == 0 )
+ return;
+ if ( msync(view, len, sync ? MS_SYNC : MS_ASYNC) )
+ problem() << "msync " << OUTPUT_ERRNO << endl;
+ }
+
+
+} // namespace mongo
+