1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// This file contains types/constants and functions specific to buffers (and in
6// particular shared buffers).
7// TODO(vtl): Reorganize this file (etc.) to separate general buffer functions
8// from (shared) buffer creation.
9//
10// Note: This header should be compilable as C.
11
12#ifndef MOJO_PUBLIC_C_SYSTEM_BUFFER_H_
13#define MOJO_PUBLIC_C_SYSTEM_BUFFER_H_
14
15#include <stdint.h>
16
17#include "mojo/public/c/system/macros.h"
18#include "mojo/public/c/system/system_export.h"
19#include "mojo/public/c/system/types.h"
20
21// |MojoCreateSharedBufferOptions|: Used to specify creation parameters for a
22// shared buffer to |MojoCreateSharedBuffer()|.
23//   |uint32_t struct_size|: Set to the size of the
24//       |MojoCreateSharedBufferOptions| struct. (Used to allow for future
25//       extensions.)
26//   |MojoCreateSharedBufferOptionsFlags flags|: Reserved for future use.
27//       |MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE|: No flags; default mode.
28//
29// TODO(vtl): Maybe add a flag to indicate whether the memory should be
30// executable or not?
31// TODO(vtl): Also a flag for discardable (ashmem-style) buffers.
32
33typedef uint32_t MojoCreateSharedBufferOptionsFlags;
34
35#ifdef __cplusplus
36const MojoCreateSharedBufferOptionsFlags
37    MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE = 0;
38#else
39#define MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE \
40  ((MojoCreateSharedBufferOptionsFlags)0)
41#endif
42
43MOJO_STATIC_ASSERT(MOJO_ALIGNOF(int64_t) == 8, "int64_t has weird alignment");
44struct MOJO_ALIGNAS(8) MojoCreateSharedBufferOptions {
45  uint32_t struct_size;
46  MojoCreateSharedBufferOptionsFlags flags;
47};
48MOJO_STATIC_ASSERT(sizeof(MojoCreateSharedBufferOptions) == 8,
49                   "MojoCreateSharedBufferOptions has wrong size");
50
51// |MojoDuplicateBufferHandleOptions|: Used to specify parameters in duplicating
52// access to a shared buffer to |MojoDuplicateBufferHandle()|.
53//   |uint32_t struct_size|: Set to the size of the
54//       |MojoDuplicateBufferHandleOptions| struct. (Used to allow for future
55//       extensions.)
56//   |MojoDuplicateBufferHandleOptionsFlags flags|: Reserved for future use.
57//       |MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE|: No flags; default
58//       mode.
59//       |MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_READ_ONLY|: The duplicate
60//       shared buffer can only be mapped read-only. A read-only duplicate can
61//       only be created before the buffer is passed over a message pipe.
62//
63// TODO(vtl): Add flags to remove writability (and executability)? Also, COW?
64
65typedef uint32_t MojoDuplicateBufferHandleOptionsFlags;
66
67#ifdef __cplusplus
68const MojoDuplicateBufferHandleOptionsFlags
69    MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE = 0;
70const MojoDuplicateBufferHandleOptionsFlags
71    MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_READ_ONLY = 1 << 0;
72#else
73#define MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE \
74  ((MojoDuplicateBufferHandleOptionsFlags)0)
75#define MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_READ_ONLY \
76  ((MojoDuplicateBufferHandleOptionsFlags)1 << 0)
77#endif
78
79struct MojoDuplicateBufferHandleOptions {
80  uint32_t struct_size;
81  MojoDuplicateBufferHandleOptionsFlags flags;
82};
83MOJO_STATIC_ASSERT(sizeof(MojoDuplicateBufferHandleOptions) == 8,
84                   "MojoDuplicateBufferHandleOptions has wrong size");
85
86// |MojoMapBufferFlags|: Used to specify different modes to |MojoMapBuffer()|.
87//   |MOJO_MAP_BUFFER_FLAG_NONE| - No flags; default mode.
88
89typedef uint32_t MojoMapBufferFlags;
90
91#ifdef __cplusplus
92const MojoMapBufferFlags MOJO_MAP_BUFFER_FLAG_NONE = 0;
93#else
94#define MOJO_MAP_BUFFER_FLAG_NONE ((MojoMapBufferFlags)0)
95#endif
96
97#ifdef __cplusplus
98extern "C" {
99#endif
100
101// Note: See the comment in functions.h about the meaning of the "optional"
102// label for pointer parameters.
103
104// Creates a buffer of size |num_bytes| bytes that can be shared between
105// applications (by duplicating the handle -- see |MojoDuplicateBufferHandle()|
106// -- and passing it over a message pipe). To access the buffer, one must call
107// |MojoMapBuffer()|.
108//
109// |options| may be set to null for a shared buffer with the default options.
110//
111// On success, |*shared_buffer_handle| will be set to the handle for the shared
112// buffer. (On failure, it is not modified.)
113//
114// Note: While more than |num_bytes| bytes may apparently be
115// available/visible/readable/writable, trying to use those extra bytes is
116// undefined behavior.
117//
118// Returns:
119//   |MOJO_RESULT_OK| on success.
120//   |MOJO_RESULT_INVALID_ARGUMENT| if some argument was invalid (e.g.,
121//       |*options| is invalid).
122//   |MOJO_RESULT_RESOURCE_EXHAUSTED| if a process/system/quota/etc. limit has
123//       been reached (e.g., if the requested size was too large, or if the
124//       maximum number of handles was exceeded).
125//   |MOJO_RESULT_UNIMPLEMENTED| if an unsupported flag was set in |*options|.
126MOJO_SYSTEM_EXPORT MojoResult MojoCreateSharedBuffer(
127    const struct MojoCreateSharedBufferOptions* options,  // Optional.
128    uint64_t num_bytes,                                   // In.
129    MojoHandle* shared_buffer_handle);                    // Out.
130
131// Duplicates the handle |buffer_handle| to a buffer. This creates another
132// handle (returned in |*new_buffer_handle| on success), which can then be sent
133// to another application over a message pipe, while retaining access to the
134// |buffer_handle| (and any mappings that it may have).
135//
136// |options| may be set to null to duplicate the buffer handle with the default
137// options.
138//
139// On success, |*shared_buffer_handle| will be set to the handle for the new
140// buffer handle. (On failure, it is not modified.)
141//
142// Returns:
143//   |MOJO_RESULT_OK| on success.
144//   |MOJO_RESULT_INVALID_ARGUMENT| if some argument was invalid (e.g.,
145//       |buffer_handle| is not a valid buffer handle or |*options| is invalid).
146//   |MOJO_RESULT_UNIMPLEMENTED| if an unsupported flag was set in |*options|.
147MOJO_SYSTEM_EXPORT MojoResult MojoDuplicateBufferHandle(
148    MojoHandle buffer_handle,
149    const struct MojoDuplicateBufferHandleOptions* options,  // Optional.
150    MojoHandle* new_buffer_handle);                          // Out.
151
152// Maps the part (at offset |offset| of length |num_bytes|) of the buffer given
153// by |buffer_handle| into memory, with options specified by |flags|. |offset +
154// num_bytes| must be less than or equal to the size of the buffer. On success,
155// |*buffer| points to memory with the requested part of the buffer. (On
156// failure, it is not modified.)
157//
158// A single buffer handle may have multiple active mappings (possibly depending
159// on the buffer type). The permissions (e.g., writable or executable) of the
160// returned memory may depend on the properties of the buffer and properties
161// attached to the buffer handle as well as |flags|.
162//
163// Note: Though data outside the specified range may apparently be
164// available/visible/readable/writable, trying to use those extra bytes is
165// undefined behavior.
166//
167// Returns:
168//   |MOJO_RESULT_OK| on success.
169//   |MOJO_RESULT_INVALID_ARGUMENT| if some argument was invalid (e.g.,
170//       |buffer_handle| is not a valid buffer handle or the range specified by
171//       |offset| and |num_bytes| is not valid).
172//   |MOJO_RESULT_RESOURCE_EXHAUSTED| if the mapping operation itself failed
173//       (e.g., due to not having appropriate address space available).
174MOJO_SYSTEM_EXPORT MojoResult MojoMapBuffer(MojoHandle buffer_handle,
175                                            uint64_t offset,
176                                            uint64_t num_bytes,
177                                            void** buffer,  // Out.
178                                            MojoMapBufferFlags flags);
179
180// Unmaps a buffer pointer that was mapped by |MojoMapBuffer()|. |buffer| must
181// have been the result of |MojoMapBuffer()| (not some other pointer inside
182// the mapped memory), and the entire mapping will be removed (partial unmapping
183// is not supported). A mapping may only be unmapped once.
184//
185// Returns:
186//   |MOJO_RESULT_OK| on success.
187//   |MOJO_RESULT_INVALID_ARGUMENT| if |buffer| is invalid (e.g., is not the
188//       result of |MojoMapBuffer()| or has already been unmapped).
189MOJO_SYSTEM_EXPORT MojoResult MojoUnmapBuffer(void* buffer);  // In.
190
191#ifdef __cplusplus
192}  // extern "C"
193#endif
194
195#endif  // MOJO_PUBLIC_C_SYSTEM_BUFFER_H_
196