| /* |
| * Copyright (C) 2006 The Android Open Source Project |
| * |
| * 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. |
| */ |
| |
| // |
| // Encapsulate a shared file mapping. |
| // |
| #ifndef __LIBS_FILE_MAP_H |
| #define __LIBS_FILE_MAP_H |
| |
| #include <sys/types.h> |
| |
| #ifdef HAVE_WIN32_FILEMAP |
| #include <windows.h> |
| #endif |
| |
| namespace android { |
| |
| /* |
| * This represents a memory-mapped file. It might be the entire file or |
| * only part of it. This requires a little bookkeeping because the mapping |
| * needs to be aligned on page boundaries, and in some cases we'd like to |
| * have multiple references to the mapped area without creating additional |
| * maps. |
| * |
| * This always uses MAP_SHARED. |
| * |
| * TODO: we should be able to create a new FileMap that is a subset of |
| * an existing FileMap and shares the underlying mapped pages. Requires |
| * completing the refcounting stuff and possibly introducing the notion |
| * of a FileMap hierarchy. |
| */ |
| class FileMap { |
| public: |
| FileMap(void); |
| |
| /* |
| * Create a new mapping on an open file. |
| * |
| * Closing the file descriptor does not unmap the pages, so we don't |
| * claim ownership of the fd. |
| * |
| * Returns "false" on failure. |
| */ |
| bool create(const char* origFileName, int fd, |
| off_t offset, size_t length, bool readOnly); |
| |
| /* |
| * Return the name of the file this map came from, if known. |
| */ |
| const char* getFileName(void) const { return mFileName; } |
| |
| /* |
| * Get a pointer to the piece of the file we requested. |
| */ |
| void* getDataPtr(void) const { return mDataPtr; } |
| |
| /* |
| * Get the length we requested. |
| */ |
| size_t getDataLength(void) const { return mDataLength; } |
| |
| /* |
| * Get the data offset used to create this map. |
| */ |
| off_t getDataOffset(void) const { return mDataOffset; } |
| |
| /* |
| * Get a "copy" of the object. |
| */ |
| FileMap* acquire(void) { mRefCount++; return this; } |
| |
| /* |
| * Call this when mapping is no longer needed. |
| */ |
| void release(void) { |
| if (--mRefCount <= 0) |
| delete this; |
| } |
| |
| /* |
| * This maps directly to madvise() values, but allows us to avoid |
| * including <sys/mman.h> everywhere. |
| */ |
| enum MapAdvice { |
| NORMAL, RANDOM, SEQUENTIAL, WILLNEED, DONTNEED |
| }; |
| |
| /* |
| * Apply an madvise() call to the entire file. |
| * |
| * Returns 0 on success, -1 on failure. |
| */ |
| int advise(MapAdvice advice); |
| |
| protected: |
| // don't delete objects; call release() |
| ~FileMap(void); |
| |
| private: |
| // these are not implemented |
| FileMap(const FileMap& src); |
| const FileMap& operator=(const FileMap& src); |
| |
| int mRefCount; // reference count |
| char* mFileName; // original file name, if known |
| void* mBasePtr; // base of mmap area; page aligned |
| size_t mBaseLength; // length, measured from "mBasePtr" |
| off_t mDataOffset; // offset used when map was created |
| void* mDataPtr; // start of requested data, offset from base |
| size_t mDataLength; // length, measured from "mDataPtr" |
| #ifdef HAVE_WIN32_FILEMAP |
| HANDLE mFileHandle; // Win32 file handle |
| HANDLE mFileMapping; // Win32 file mapping handle |
| #endif |
| |
| static long mPageSize; |
| }; |
| |
| }; // namespace android |
| |
| #endif // __LIBS_FILE_MAP_H |