summaryrefslogtreecommitdiff
path: root/mojo/public/c/system/buffer.h
blob: 83b198b2a89a9ff3a9ed75cbed3fc99b57de8676 (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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file contains types/constants and functions specific to shared buffers.
//
// Note: This header should be compilable as C.

#ifndef MOJO_PUBLIC_C_SYSTEM_BUFFER_H_
#define MOJO_PUBLIC_C_SYSTEM_BUFFER_H_

#include <stdint.h>

#include "mojo/public/c/system/macros.h"
#include "mojo/public/c/system/system_export.h"
#include "mojo/public/c/system/types.h"

// Flags passed to |MojoCreateSharedBuffer()| via
// |MojoCreateSharedBufferOptions|. See values defined below.
typedef uint32_t MojoCreateSharedBufferFlags;

// No flags. Default behavior.
#define MOJO_CREATE_SHARED_BUFFER_FLAG_NONE ((uint32_t)0)

// Options passed to |MojoCreateSharedBuffer()|.
struct MOJO_ALIGNAS(8) MojoCreateSharedBufferOptions {
  // The size of this structure, used for versioning.
  uint32_t struct_size;

  // See |MojoCreateSharedBufferFlags|.
  MojoCreateSharedBufferFlags flags;
};
MOJO_STATIC_ASSERT(MOJO_ALIGNOF(int64_t) <= 8, "int64_t has weird alignment");
MOJO_STATIC_ASSERT(sizeof(MojoCreateSharedBufferOptions) == 8,
                   "MojoCreateSharedBufferOptions has wrong size");

// Flags passed to |MojoGetBufferInfo()| via |MojoGetBufferInfoOptions|. See
// values defined below.
typedef uint32_t MojoGetBufferInfoFlags;

// No flags. Default behavior.
#define MOJO_GET_BUFFER_INFO_FLAG_NONE ((uint32_t)0)

// Options passed to |MojoGetBufferInfo()|.
struct MOJO_ALIGNAS(8) MojoGetBufferInfoOptions {
  // The size of this structure, used for versioning.
  uint32_t struct_size;

  // See |MojoGetBufferInfoFlags|.
  MojoGetBufferInfoFlags flags;
};
MOJO_STATIC_ASSERT(sizeof(MojoGetBufferInfoOptions) == 8,
                   "MojoSharedBufferOptions has wrong size");

// Structure used to receive information about a shared buffer via
// |MojoGetBufferInfo()|.
struct MOJO_ALIGNAS(8) MojoSharedBufferInfo {
  // The size of this structure, used for versioning.
  uint32_t struct_size;

  // The size of the shared buffer.
  uint64_t size;
};
MOJO_STATIC_ASSERT(sizeof(MojoSharedBufferInfo) == 16,
                   "MojoSharedBufferInfo has wrong size");

// Flags passed to |MojoDuplicateBufferHandle()| via
// |MojoDuplicateBufferHandleOptions|. See values defined below.
typedef uint32_t MojoDuplicateBufferHandleFlags;

// No options. Default behavior. Note that if a shared buffer handle is ever
// duplicated without |MOJO_DUPLICATE_BUFFER_HANDLE_READ_ONLY| (see below),
// neither it nor any of its duplicates can ever be duplicated *with*
// |MOJO_DUPLICATE_BUFFER_HANDLE_READ_ONLY| in the future. That is, once a
// writable handle has been duplicated as another writable handle, it is no
// longer possible to create read-only handles to the underlying buffer object.
#define MOJO_DUPLICATE_BUFFER_HANDLE_FLAG_NONE ((uint32_t)0)

// Duplicates the handle as read-only. If successful, the resulting new handle
// will always map to a read-only memory region. Successful use of this flag
// also imposes the limitation that the handle or any of its subsequent
// duplicates may never be duplicated *without* this flag in the future. That
// is, once a read-only handle is produced for a buffer object, all future
// handles to that object must also be read-only.
#define MOJO_DUPLICATE_BUFFER_HANDLE_FLAG_READ_ONLY ((uint32_t)1 << 0)

// Options passed to |MojoDuplicateBufferHandle()|.
struct MojoDuplicateBufferHandleOptions {
  // The size of this structure, used for versioning.
  uint32_t struct_size;

  // See |MojoDuplicateBufferHandleFlags|.
  MojoDuplicateBufferHandleFlags flags;
};
MOJO_STATIC_ASSERT(sizeof(MojoDuplicateBufferHandleOptions) == 8,
                   "MojoDuplicateBufferHandleOptions has wrong size");

// Flags passed to |MojoMapBuffer()| via |MojoMapBufferOptions|. See values
// defined below.
typedef uint32_t MojoMapBufferFlags;

// No flags. Default behavior.
#define MOJO_MAP_BUFFER_FLAG_NONE ((uint32_t)0)

// Options passed to |MojoMapBuffer()|.
struct MojoMapBufferOptions {
  // The size of this structure, used for versioning.
  uint32_t struct_size;

  // See |MojoMapBufferFlags|.
  MojoMapBufferFlags flags;
};
MOJO_STATIC_ASSERT(sizeof(MojoMapBufferOptions) == 8,
                   "MojoMapBufferOptions has wrong size");

#ifdef __cplusplus
extern "C" {
#endif

// Creates a buffer of size |num_bytes| bytes that can be shared between
// processes. The returned handle may be duplicated any number of times by
// |MojoDuplicateBufferHandle()|.
//
// To access the buffer's storage, one must call |MojoMapBuffer()|.
//
// |options| may be set to null for a shared buffer with the default options.
//
// On success, |*shared_buffer_handle| will be set to the handle for the shared
// buffer. On failure it is not modified.
//
// Returns:
//   |MOJO_RESULT_OK| on success.
//   |MOJO_RESULT_INVALID_ARGUMENT| if some argument was invalid (e.g.,
//       |*options| is invalid).
//   |MOJO_RESULT_RESOURCE_EXHAUSTED| if a process/system/quota/etc. limit has
//       been reached (e.g., if the requested size was too large, or if the
//       maximum number of handles was exceeded).
//   |MOJO_RESULT_UNIMPLEMENTED| if an unsupported flag was set in |*options|.
MOJO_SYSTEM_EXPORT MojoResult
MojoCreateSharedBuffer(uint64_t num_bytes,
                       const struct MojoCreateSharedBufferOptions* options,
                       MojoHandle* shared_buffer_handle);

// Duplicates the handle |buffer_handle| as a new shared buffer handle. On
// success this returns the new handle in |*new_buffer_handle|. A shared buffer
// remains allocated as long as there is at least one shared buffer handle
// referencing it in at least one process in the system.
//
// |options| may be set to null to duplicate the buffer handle with the default
// options.
//
// Access rights to mapped memory from the duplicated handle may be controlled
// by flags in |*options|, with some limitations. See notes on
// |MOJO_DUPLICATE_BUFFER_HANDLE_FLAG_NONE| and
// |MOJO_DUPLICATE_BUFFER_HANDLE_FLAG_READ_ONLY| regarding restrictions on
// duplication with respect to these flags.
//
// Returns:
//   |MOJO_RESULT_OK| on success.
//   |MOJO_RESULT_INVALID_ARGUMENT| if some argument was invalid (e.g.,
//       |buffer_handle| is not a valid buffer handle or |*options| is invalid).
//   |MOJO_RESULT_UNIMPLEMENTED| if an unsupported flag was set in |*options|.
//   |MOJO_RESULT_FAILED_PRECONDITION| if
//       |MOJO_DUPLICATE_BUFFER_HANDLE_FLAG_READ_ONLY| was set but the handle
//       was already previously duplicated without that flag; or if
//       |MOJO_DUPLICATE_BUFFER_HANDLE_FLAG_READ_ONLY| was not set but the
//       handle was already previously duplicated with that flag.
MOJO_SYSTEM_EXPORT MojoResult MojoDuplicateBufferHandle(
    MojoHandle buffer_handle,
    const struct MojoDuplicateBufferHandleOptions* options,
    MojoHandle* new_buffer_handle);

// Maps the part (at offset |offset| of length |num_bytes|) of the buffer given
// by |buffer_handle| into memory, with options specified by |options|.
// |offset+num_bytes| must be less than or equal to the size of the buffer. On
// success, |*buffer| points to memory with the requested part of the buffer. On
// failure |*buffer| it is not modified.
//
// A single buffer handle may have multiple active mappings. The permissions
// (e.g., writable or executable) of the returned memory depend on the
// properties of the buffer and properties attached to the buffer handle, as
// well as |flags|.
//
// A mapped buffer must eventually be unmapped by calling |MojoUnmapBuffer()|
// with the value of |*buffer| returned by this function.
//
// |options| may be null to map the buffer with default behavior.
//
// Returns:
//   |MOJO_RESULT_OK| on success.
//   |MOJO_RESULT_INVALID_ARGUMENT| if some argument was invalid (e.g.,
//       |buffer_handle| is not a valid buffer handle, the range specified by
//       |offset| and |num_bytes| is not valid, or |*options| is invalid).
//   |MOJO_RESULT_RESOURCE_EXHAUSTED| if the mapping operation itself failed
//       (e.g., due to not having appropriate address space available).
MOJO_SYSTEM_EXPORT MojoResult
MojoMapBuffer(MojoHandle buffer_handle,
              uint64_t offset,
              uint64_t num_bytes,
              const struct MojoMapBufferOptions* options,
              void** buffer);

// Unmaps a buffer pointer that was mapped by |MojoMapBuffer()|. |buffer| must
// have been the result of |MojoMapBuffer()| (not some other pointer inside
// the mapped memory), and the entire mapping will be removed.
//
// A mapping may only be unmapped once.
//
// Returns:
//   |MOJO_RESULT_OK| on success.
//   |MOJO_RESULT_INVALID_ARGUMENT| if |buffer| is invalid (e.g., is not the
//       result of |MojoMapBuffer()| or has already been unmapped).
MOJO_SYSTEM_EXPORT MojoResult MojoUnmapBuffer(void* buffer);

// Retrieve information about |buffer_handle| into |info|.
//
// Callers must initialize |info->struct_size| to |sizeof(MojoSharedBufferInfo)|
// before calling this function.
//
// |options| may be null for default options.
//
// Returns:
//   |MOJO_RESULT_OK| on success.
//   |MOJO_RESULT_INVALID_ARGUMENT| if |buffer_handle| is invalid, |info| is
//       null, or |*options| is invalid.
//
// On success, |info->size| will be set to the size of the buffer. On failure it
// is not modified.
MOJO_SYSTEM_EXPORT MojoResult
MojoGetBufferInfo(MojoHandle buffer_handle,
                  const struct MojoGetBufferInfoOptions* options,
                  struct MojoSharedBufferInfo* info);

#ifdef __cplusplus
}  // extern "C"
#endif

#endif  // MOJO_PUBLIC_C_SYSTEM_BUFFER_H_