// Copyright 2016 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/functions and constants for platform handle wrapping
// and unwrapping APIs.
//
// Note: This header should be compilable as C.
#ifndef MOJO_PUBLIC_C_SYSTEM_PLATFORM_HANDLE_H_
#define MOJO_PUBLIC_C_SYSTEM_PLATFORM_HANDLE_H_
#include <stdint.h>
#include "mojo/public/c/system/system_export.h"
#include "mojo/public/c/system/types.h"
#ifdef __cplusplus
extern "C" {
#endif
// The type of handle value contained in a |MojoPlatformHandle| structure.
typedef uint32_t MojoPlatformHandleType;
// An invalid handle value. Other contents of the |MojoPlatformHandle| are
// ignored.
#define MOJO_PLATFORM_HANDLE_TYPE_INVALID ((MojoPlatformHandleType)0)
// The |MojoPlatformHandle| value represents a POSIX file descriptor. Only
// usable on POSIX host systems (e.g. Android, Linux, Chrome OS, Mac).
#define MOJO_PLATFORM_HANDLE_TYPE_FILE_DESCRIPTOR ((MojoPlatformHandleType)1)
// The |MojoPlatformHandle| value represents a Mach port right (e.g. a value
// opaquely of type |mach_port_t|). Only usable on Mac OS X hosts.
#define MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT ((MojoPlatformHandleType)2)
// The |MojoPlatformHandle| value represents a Windows HANDLE value. Only usable
// on Windows hosts.
#define MOJO_PLATFORM_HANDLE_TYPE_WINDOWS_HANDLE ((MojoPlatformHandleType)3)
// The |MojoPlatformHandle| value represents a Fuchsia system handle. Only
// usable on Fuchsia hosts.
#define MOJO_PLATFORM_HANDLE_TYPE_FUCHSIA_HANDLE ((MojoPlatformHandleType)4)
// |MojoPlatformHandle|: A handle to a native platform object.
//
// |uint32_t struct_size|: The size of this structure. Used for versioning
// to allow for future extensions.
//
// |MojoPlatformHandleType type|: The type of handle stored in |value|.
//
// |uint64_t value|: The value of this handle. Ignored if |type| is
// MOJO_PLATFORM_HANDLE_TYPE_INVALID. Otherwise the meaning of this
// value depends on the value of |type|.
//
// Represents a native platform handle value for coersion to or from a wrapping
// Mojo handle.
struct MOJO_ALIGNAS(8) MojoPlatformHandle {
// The size of this structure, used for versioning.
uint32_t struct_size;
// The type of platform handle represented by |value|.
MojoPlatformHandleType type;
// An opaque representation of the native platform handle. Interpretation and
// treatment of this value by Mojo depends on the value of |type|.
uint64_t value;
};
MOJO_STATIC_ASSERT(sizeof(MojoPlatformHandle) == 16,
"MojoPlatformHandle has wrong size");
// Flags passed to |MojoWrapPlatformHandle()| via
// |MojoWrapPlatformHandleOptions|.
typedef uint32_t MojoWrapPlatformHandleFlags;
// No flags. Default behavior.
#define MOJO_WRAP_PLATFORM_HANDLE_FLAG_NONE ((MojoWrapPlatformHandleFlags)0)
// Options passed to |MojoWrapPlatformHandle()|.
struct MOJO_ALIGNAS(8) MojoWrapPlatformHandleOptions {
// The size of this structure, used for versioning.
uint32_t struct_size;
// See |MojoWrapPlatformHandleFlags|.
MojoWrapPlatformHandleFlags flags;
};
MOJO_STATIC_ASSERT(sizeof(MojoWrapPlatformHandleOptions) == 8,
"MojoWrapPlatformHandleOptions has wrong size");
// Flags passed to |MojoUnwrapPlatformHandle()| via
// |MojoUnwrapPlatformHandleOptions|.
typedef uint32_t MojoUnwrapPlatformHandleFlags;
// No flags. Default behavior.
#define MOJO_UNWRAP_PLATFORM_HANDLE_FLAG_NONE ((MojoUnwrapPlatformHandleFlags)0)
// Options passed to |MojoUnwrapPlatformHandle()|.
struct MOJO_ALIGNAS(8) MojoUnwrapPlatformHandleOptions {
// The size of this structure, used for versioning.
uint32_t struct_size;
// See |MojoUnwrapPlatformHandleFlags|.
MojoUnwrapPlatformHandleFlags flags;
};
MOJO_STATIC_ASSERT(sizeof(MojoUnwrapPlatformHandleOptions) == 8,
"MojoUnwrapPlatformHandleOptions has wrong size");
// A GUID value used to identify the shared memory region backing a Mojo shared
// buffer handle.
struct MOJO_ALIGNAS(8) MojoSharedBufferGuid {
uint64_t high;
uint64_t low;
};
// The access type of shared memory region wrapped by a Mojo shared buffer
// handle. See values defined below.
typedef uint32_t MojoPlatformSharedMemoryRegionAccessMode;
// The region is read-only, meaning there is at most one writable mapped handle
// to the region somewhere, and there are any number of handles (including this
// one) which can only be mapped read-only.
//
// WARNING: See notes in |MojoWrapPlatformSharedMemoryRegion()| about the
// meaning and usage of different access modes. This CANNOT be used to change
// a buffer's access mode; it is merely an informational value to allow Mojo
// to retain consistency between wrapping and unwrapping of buffer handles.
#define MOJO_PLATFORM_SHARED_MEMORY_REGION_ACCESS_MODE_READ_ONLY \
((MojoPlatformSharedMemoryRegionAccessMode)0)
// The region is writable, meaning there is exactly one handle to the region and
// it is mappable read/writable.
//
// WARNING: See notes in |MojoWrapPlatformSharedMemoryRegion()| about the
// meaning and usage of different access modes. This CANNOT be used to change
// a buffer's access mode; it is merely an informational value to allow Mojo
// to retain consistency between wrapping and unwrapping of buffer handles.
#define MOJO_PLATFORM_SHARED_MEMORY_REGION_ACCESS_MODE_WRITABLE \
((MojoPlatformSharedMemoryRegionAccessMode)1)
// The region is unsafe, meaning any number of read/writable handles may refer
// to it.
//
// WARNING: See notes in |MojoWrapPlatformSharedMemoryRegion()| about the
// meaning and usage of different access modes. This CANNOT be used to change
// a buffer's access mode; it is merely an informational value to allow Mojo
// to retain consistency between wrapping and unwrapping of buffer handles.
#define MOJO_PLATFORM_SHARED_MEMORY_REGION_ACCESS_MODE_UNSAFE \
((MojoPlatformSharedMemoryRegionAccessMode)2)
// Flags passed to |MojoWrapPlatformSharedMemoryRegion()| via
// |MojoWrapPlatformSharedMemoryRegionOptions|.
typedef uint32_t MojoWrapPlatformSharedMemoryRegionFlags;
// No flags. Default behavior.
#define MOJO_WRAP_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_NONE \
((MojoWrapPlatformSharedMemoryRegionFlags)0)
// Options passed to |MojoWrapPlatformSharedMemoryRegion()|.
struct MOJO_ALIGNAS(8) MojoWrapPlatformSharedMemoryRegionOptions {
// The size of this structure, used for versioning.
uint32_t struct_size;
// See |MojoWrapPlatformSharedMemoryRegionFlags|.
MojoWrapPlatformSharedMemoryRegionFlags flags;
};
MOJO_STATIC_ASSERT(sizeof(MojoWrapPlatformSharedMemoryRegionOptions) == 8,
"MojoWrapPlatformSharedMemoryRegionOptions has wrong size");
// Flags passed to |MojoUnwrapPlatformSharedMemoryRegion()| via
// |MojoUnwrapPlatformSharedMemoryRegionOptions|.
typedef uint32_t MojoUnwrapPlatformSharedMemoryRegionFlags;
// No flags. Default behavior.
#define MOJO_UNWRAP_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_NONE \
((MojoUnwrapPlatformSharedMemoryRegionFlags)0)
// Options passed to |MojoUnwrapPlatformSharedMemoryRegion()|.
struct MOJO_ALIGNAS(8) MojoUnwrapPlatformSharedMemoryRegionOptions {
// The size of this structure, used for versioning.
uint32_t struct_size;
// See |MojoUnwrapPlatformSharedMemoryRegionFlags|.
MojoUnwrapPlatformSharedMemoryRegionFlags flags;
};
MOJO_STATIC_ASSERT(
sizeof(MojoUnwrapPlatformSharedMemoryRegionOptions) == 8,
"MojoUnwrapPlatformSharedMemoryRegionOptions has wrong size");
// Wraps a native platform handle as a Mojo handle which can be transferred
// over a message pipe. Takes ownership of the underlying native platform
// object. i.e. if you wrap a POSIX file descriptor or Windows HANDLE and then
// call |MojoClose()| on the resulting MojoHandle, the underlying file
// descriptor or HANDLE will be closed.
//
// |platform_handle|: The platform handle to wrap.
//
// |options| may be null.
//
// Returns:
// |MOJO_RESULT_OK| if the handle was successfully wrapped. In this case
// |*mojo_handle| contains the Mojo handle of the wrapped object.
// |MOJO_RESULT_RESOURCE_EXHAUSTED| if the system is out of handles.
// |MOJO_RESULT_INVALID_ARGUMENT| if |platform_handle| was not a valid
// platform handle.
//
// NOTE: It is not always possible to detect if |platform_handle| is valid,
// particularly when |platform_handle->type| is valid but
// |platform_handle->value| does not represent a valid platform object.
MOJO_SYSTEM_EXPORT MojoResult
MojoWrapPlatformHandle(const struct MojoPlatformHandle* platform_handle,
const struct MojoWrapPlatformHandleOptions* options,
MojoHandle* mojo_handle);
// Unwraps a native platform handle from a Mojo handle. If this call succeeds,
// ownership of the underlying platform object is assumed by the caller. The
// The Mojo handle is always closed regardless of success or failure.
//
// |mojo_handle|: The Mojo handle from which to unwrap the native platform
// handle.
//
// |options| may be null.
//
// Returns:
// |MOJO_RESULT_OK| if the handle was successfully unwrapped. In this case
// |*platform_handle| contains the unwrapped platform handle.
// |MOJO_RESULT_INVALID_ARGUMENT| if |mojo_handle| was not a valid Mojo
// handle wrapping a platform handle.
MOJO_SYSTEM_EXPORT MojoResult
MojoUnwrapPlatformHandle(MojoHandle mojo_handle,
const struct MojoUnwrapPlatformHandleOptions* options,
struct MojoPlatformHandle* platform_handle);
// Wraps a native platform shared memory region with a Mojo shared buffer handle
// which can be used exactly like a shared buffer handle created by
// |MojoCreateSharedBuffer()| or |MojoDuplicateBufferHandle()|.
//
// Takes ownership of the native platform shared buffer handle(s).
//
// |platform_handles|: The platform handle(s) to wrap. Must be one or more
// native handles representing a shared memory region. On POSIX systems
// with |access_mode| set to
// |MOJO_PLATFORM_SHARED_MEMORY_REGION_ACCESS_MODE_WRITABLE| this must have
// two handles, with the second one being a handle opened for read-only
// mapping. For all other platforms and all other access modes, there should
// be only one handle.
// |num_platform_handles|: The number of platform handles given in
// |platform_handles|. See note above.
// |num_bytes|: The size of the shared memory region in bytes.
// |access_mode|: The current access mode of the shared memory region.
// |options|: Options to control behavior. May be null.
//
// !!WARNING!!: |access_mode| DOES NOT CONTROL ACCESS TO THE REGION. It is an
// informational field used by Mojo to ensure end-to-end consistency when
// wrapping and unwrapping region handles. The caller is responsible for
// ensuring that wrapped handles are already subject to the access constraints
// conveyed by |access_mode|.
//
// Returns:
// |MOJO_RESULT_OK| if the handle was successfully wrapped. In this case
// |*mojo_handle| contains a Mojo shared buffer handle.
// |MOJO_RESULT_INVALID_ARGUMENT| if |platform_handle| was not a valid
// platform shared buffer handle.
MOJO_SYSTEM_EXPORT MojoResult MojoWrapPlatformSharedMemoryRegion(
const struct MojoPlatformHandle* platform_handles,
uint32_t num_platform_handles,
uint64_t num_bytes,
const struct MojoSharedBufferGuid* guid,
MojoPlatformSharedMemoryRegionAccessMode access_mode,
const struct MojoWrapPlatformSharedMemoryRegionOptions* options,
MojoHandle* mojo_handle);
// Unwraps a native platform shared memory region from a Mojo shared buffer
// handle. If this call succeeds, ownership of the underlying shared buffer
// object is assumed by the caller.
//
// The Mojo handle is always closed regardless of success or failure.
//
// |mojo_handle|: The Mojo shared buffer handle to unwrap.
//
// On input, |*num_platform_handles| must be non-zero, and |platform_handles|
// should point to enough memory to hold at least that many |MojoPlatformHandle|
// values. Each element in |platform_handles| must have also initialized
// |struct_size| to the caller's known |sizeof(MojoPlatformHandle)|.
//
// |platform_handles|, |num_platform_handles|, |num_bytes| and |access_mode| are
// all used to receive output values and MUST always be non-null.
//
// |options| may be null.
//
// NOTE: On POSIX systems when unwrapping regions with the
// |MOJO_PLATFORM_SHARED_MEMORY_REGION_ACCESS_MODE_WRITABLE| access mode,
// this will always unwrap two platform handles, with the first one being a
// POSIX file descriptor which can be mapped to writable memory, and the second
// one being a POSIX file descriptor which can only be mapped read-only. For all
// other access modes and all other platforms, this always unwraps to a single
// platform handle.
//
// Returns:
// |MOJO_RESULT_OK| if the handle was successfully unwrapped. In this case
// |*platform_handles| contains one or more platform handles to represent
// the unwrapped region, |*num_platform_handles| contains the number of
// platform handles actually stored in |platform_handles| on output,
// |*num_bytes| contains the size of the shared buffer object, and
// |*access_mode| indicates the access mode of the region.
// |MOJO_RESULT_INVALID_ARGUMENT| if |mojo_handle| is not a valid Mojo
// shared buffer handle or |*num_platform_handles| is not large enough
// to hold all the handles that would have been unwrapped on success.
MOJO_SYSTEM_EXPORT MojoResult MojoUnwrapPlatformSharedMemoryRegion(
MojoHandle mojo_handle,
const struct MojoUnwrapPlatformSharedMemoryRegionOptions* options,
struct MojoPlatformHandle* platform_handles,
uint32_t* num_platform_handles,
uint64_t* num_bytes,
struct MojoSharedBufferGuid* guid,
MojoPlatformSharedMemoryRegionAccessMode* access_mode);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // MOJO_PUBLIC_C_SYSTEM_PLATFORM_HANDLE_H_