1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//
18// Encapsulate a shared file mapping.
19//
20#ifndef __LIBS_FILE_MAP_H
21#define __LIBS_FILE_MAP_H
22
23#include <sys/types.h>
24
25#include <utils/Compat.h>
26
27#ifdef HAVE_WIN32_FILEMAP
28#include <windows.h>
29#endif
30
31namespace android {
32
33/*
34 * This represents a memory-mapped file.  It might be the entire file or
35 * only part of it.  This requires a little bookkeeping because the mapping
36 * needs to be aligned on page boundaries, and in some cases we'd like to
37 * have multiple references to the mapped area without creating additional
38 * maps.
39 *
40 * This always uses MAP_SHARED.
41 *
42 * TODO: we should be able to create a new FileMap that is a subset of
43 * an existing FileMap and shares the underlying mapped pages.  Requires
44 * completing the refcounting stuff and possibly introducing the notion
45 * of a FileMap hierarchy.
46 */
47class FileMap {
48public:
49    FileMap(void);
50
51    /*
52     * Create a new mapping on an open file.
53     *
54     * Closing the file descriptor does not unmap the pages, so we don't
55     * claim ownership of the fd.
56     *
57     * Returns "false" on failure.
58     */
59    bool create(const char* origFileName, int fd,
60                off64_t offset, size_t length, bool readOnly);
61
62    /*
63     * Return the name of the file this map came from, if known.
64     */
65    const char* getFileName(void) const { return mFileName; }
66
67    /*
68     * Get a pointer to the piece of the file we requested.
69     */
70    void* getDataPtr(void) const { return mDataPtr; }
71
72    /*
73     * Get the length we requested.
74     */
75    size_t getDataLength(void) const { return mDataLength; }
76
77    /*
78     * Get the data offset used to create this map.
79     */
80    off64_t getDataOffset(void) const { return mDataOffset; }
81
82    /*
83     * Get a "copy" of the object.
84     */
85    FileMap* acquire(void) { mRefCount++; return this; }
86
87    /*
88     * Call this when mapping is no longer needed.
89     */
90    void release(void) {
91        if (--mRefCount <= 0)
92            delete this;
93    }
94
95    /*
96     * This maps directly to madvise() values, but allows us to avoid
97     * including <sys/mman.h> everywhere.
98     */
99    enum MapAdvice {
100        NORMAL, RANDOM, SEQUENTIAL, WILLNEED, DONTNEED
101    };
102
103    /*
104     * Apply an madvise() call to the entire file.
105     *
106     * Returns 0 on success, -1 on failure.
107     */
108    int advise(MapAdvice advice);
109
110protected:
111    // don't delete objects; call release()
112    ~FileMap(void);
113
114private:
115    // these are not implemented
116    FileMap(const FileMap& src);
117    const FileMap& operator=(const FileMap& src);
118
119    int         mRefCount;      // reference count
120    char*       mFileName;      // original file name, if known
121    void*       mBasePtr;       // base of mmap area; page aligned
122    size_t      mBaseLength;    // length, measured from "mBasePtr"
123    off64_t     mDataOffset;    // offset used when map was created
124    void*       mDataPtr;       // start of requested data, offset from base
125    size_t      mDataLength;    // length, measured from "mDataPtr"
126#ifdef HAVE_WIN32_FILEMAP
127    HANDLE      mFileHandle;    // Win32 file handle
128    HANDLE      mFileMapping;   // Win32 file mapping handle
129#endif
130
131    static long mPageSize;
132};
133
134}; // namespace android
135
136#endif // __LIBS_FILE_MAP_H
137