summaryrefslogtreecommitdiffstats
path: root/include/utils/FileMap.h
blob: 8dfd3bea6dab20b68e0b1122ceb384b1e36c30dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * 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