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#if defined(__MINGW32__)
28// Ensure that we always pull in winsock2.h before windows.h
29#if defined(_WIN32)
30#include <winsock2.h>
31#endif
32#include <windows.h>
33#endif
34
35namespace android {
36
37/*
38 * This represents a memory-mapped file.  It might be the entire file or
39 * only part of it.  This requires a little bookkeeping because the mapping
40 * needs to be aligned on page boundaries, and in some cases we'd like to
41 * have multiple references to the mapped area without creating additional
42 * maps.
43 *
44 * This always uses MAP_SHARED.
45 *
46 * TODO: we should be able to create a new FileMap that is a subset of
47 * an existing FileMap and shares the underlying mapped pages.  Requires
48 * completing the refcounting stuff and possibly introducing the notion
49 * of a FileMap hierarchy.
50 */
51class FileMap {
52public:
53    FileMap(void);
54
55    FileMap(FileMap&& f);
56    FileMap& operator=(FileMap&& f);
57
58    /*
59     * Create a new mapping on an open file.
60     *
61     * Closing the file descriptor does not unmap the pages, so we don't
62     * claim ownership of the fd.
63     *
64     * Returns "false" on failure.
65     */
66    bool create(const char* origFileName, int fd,
67                off64_t offset, size_t length, bool readOnly);
68
69    ~FileMap(void);
70
71    /*
72     * Return the name of the file this map came from, if known.
73     */
74    const char* getFileName(void) const { return mFileName; }
75
76    /*
77     * Get a pointer to the piece of the file we requested.
78     */
79    void* getDataPtr(void) const { return mDataPtr; }
80
81    /*
82     * Get the length we requested.
83     */
84    size_t getDataLength(void) const { return mDataLength; }
85
86    /*
87     * Get the data offset used to create this map.
88     */
89    off64_t getDataOffset(void) const { return mDataOffset; }
90
91    /*
92     * This maps directly to madvise() values, but allows us to avoid
93     * including <sys/mman.h> everywhere.
94     */
95    enum MapAdvice {
96        NORMAL, RANDOM, SEQUENTIAL, WILLNEED, DONTNEED
97    };
98
99    /*
100     * Apply an madvise() call to the entire file.
101     *
102     * Returns 0 on success, -1 on failure.
103     */
104    int advise(MapAdvice advice);
105
106protected:
107
108private:
109    // these are not implemented
110    FileMap(const FileMap& src);
111    const FileMap& operator=(const FileMap& src);
112
113    char*       mFileName;      // original file name, if known
114    void*       mBasePtr;       // base of mmap area; page aligned
115    size_t      mBaseLength;    // length, measured from "mBasePtr"
116    off64_t     mDataOffset;    // offset used when map was created
117    void*       mDataPtr;       // start of requested data, offset from base
118    size_t      mDataLength;    // length, measured from "mDataPtr"
119#if defined(__MINGW32__)
120    HANDLE      mFileHandle;    // Win32 file handle
121    HANDLE      mFileMapping;   // Win32 file mapping handle
122#endif
123
124    static long mPageSize;
125};
126
127}; // namespace android
128
129#endif // __LIBS_FILE_MAP_H
130