You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
323 lines
13 KiB
323 lines
13 KiB
// Copyright 2017 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.
|
|
|
|
#ifndef MOJO_PUBLIC_C_SYSTEM_TRAP_H_
|
|
#define MOJO_PUBLIC_C_SYSTEM_TRAP_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 trap event handlers within |MojoTrapEvent|.
|
|
typedef uint32_t MojoTrapEventFlags;
|
|
|
|
#ifdef __cplusplus
|
|
const MojoTrapEventFlags MOJO_TRAP_EVENT_FLAG_NONE = 0;
|
|
const MojoTrapEventFlags MOJO_TRAP_EVENT_FLAG_WITHIN_API_CALL = 1 << 0;
|
|
#else
|
|
#define MOJO_TRAP_EVENT_FLAG_NONE ((MojoTrapEventFlags)0)
|
|
#define MOJO_TRAP_EVENT_FLAG_WITHIN_API_CALL ((MojoTrapEventFlags)1 << 0)
|
|
#endif
|
|
|
|
// Structure passed to trap event handlers when invoked by a tripped trap.
|
|
struct MOJO_ALIGNAS(8) MojoTrapEvent {
|
|
// The size of this structure, used for versioning.
|
|
uint32_t struct_size;
|
|
|
|
// May take on some combination of the following values:
|
|
//
|
|
// |MOJO_TRAP_EVENT_FLAG_NONE|: No flags.
|
|
//
|
|
// |MOJO_TRAP_EVENT_FLAG_WITHIN_API_CALL|: The trap was tripped within the
|
|
// extent of a user call to some Mojo API. This means that the event
|
|
// handler itself is re-entering user code. May happen, for example, if
|
|
// user code writes to an intra-process pipe and the receiving end trips
|
|
// a trap as a result. In that case the event handler executes within
|
|
// the extent of the |MojoWriteMessage()| call.
|
|
MojoTrapEventFlags flags;
|
|
|
|
// The context for the trigger which tripped the trap.
|
|
MOJO_POINTER_FIELD(uintptr_t, trigger_context);
|
|
|
|
// A result code indicating the cause of the event. May take on any of the
|
|
// following values:
|
|
//
|
|
// |MOJO_RESULT_OK|: The trigger's conditions were met.
|
|
// |MOJO_RESULT_FAILED_PRECONDITION|: The trigger's observed handle has
|
|
// changed state in such a way that the trigger's conditions can never
|
|
// be met again.
|
|
// |MOJO_RESULT_CANCELLED|: The trigger has been removed and will never
|
|
// cause another event to fire. This is always the last event fired by
|
|
// a trigger and it will fire when: the trigger is explicitly removed
|
|
// with |MojoRemoteTrigger()|, the trigger's owning trap handle is
|
|
// closed, or the handle observed by the trigger is closed.
|
|
//
|
|
// Unlike the other result types above |MOJO_RESULT_CANCELLED| can
|
|
// fire even when the trap is disarmed.
|
|
MojoResult result;
|
|
|
|
// The last known signalling state of the trigger's observed handle at the
|
|
// time the trap was tripped.
|
|
struct MojoHandleSignalsState signals_state;
|
|
};
|
|
MOJO_STATIC_ASSERT(sizeof(MojoTrapEvent) == 32,
|
|
"MojoTrapEvent has wrong size.");
|
|
|
|
// Value given to |MojoAddTrigger| to configure what condition should cause it
|
|
// to trip its trap. May be one of the following values:
|
|
//
|
|
// |MOJO_TRIGGER_CONDITION_SIGNALS_UNSATISFIED| - A trigger added with this
|
|
// condition will trip its trap when any of its observed signals
|
|
// transition from being satisfied to being unsatisfied.
|
|
// |MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED| - A triger added with this
|
|
// condition will trip its trap when any of its observed signals
|
|
// transition from being unsatisfied to being satisfied, or when none of
|
|
// the observed signals can ever be satisfied again.
|
|
typedef uint32_t MojoTriggerCondition;
|
|
|
|
#ifdef __cplusplus
|
|
const MojoTriggerCondition MOJO_TRIGGER_CONDITION_SIGNALS_UNSATISFIED = 0;
|
|
const MojoTriggerCondition MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED = 1;
|
|
#else
|
|
#define MOJO_TRIGGER_CONDITION_SIGNALS_UNSATISFIED ((MojoTriggerCondition)0)
|
|
#define MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED ((MojoTriggerCondition)1)
|
|
#endif
|
|
|
|
// Flags passed to |MojoCreateTrap()| via |MojoCreateTrapOptions|.
|
|
typedef uint32_t MojoCreateTrapFlags;
|
|
|
|
#ifdef __cplusplus
|
|
const MojoCreateTrapFlags MOJO_CREATE_TRAP_FLAG_NONE = 0;
|
|
#else
|
|
#define MOJO_CREATE_TRAP_FLAG_NONE ((MojoCreateTrapFlags)0)
|
|
#endif
|
|
|
|
// Options passed to |MojoCreateTrap()|.
|
|
struct MOJO_ALIGNAS(8) MojoCreateTrapOptions {
|
|
// The size of this structure, used for versioning.
|
|
uint32_t struct_size;
|
|
|
|
// Flags. Currently unused.
|
|
MojoCreateTrapFlags flags;
|
|
};
|
|
MOJO_STATIC_ASSERT(sizeof(MojoCreateTrapOptions) == 8,
|
|
"MojoCreateTrapOptions has wrong size.");
|
|
|
|
// Flags passed to |MojoAddTrigger()| via |MojoAddTriggerOptions|.
|
|
typedef uint32_t MojoAddTriggerFlags;
|
|
|
|
#ifdef __cplusplus
|
|
const MojoAddTriggerFlags MOJO_ADD_TRIGGER_FLAG_NONE = 0;
|
|
#else
|
|
#define MOJO_ADD_TRIGGER_FLAG_NONE ((MojoAddTriggerFlags)0)
|
|
#endif
|
|
|
|
// Options passed to |MojoAddTrigger()|.
|
|
struct MOJO_ALIGNAS(8) MojoAddTriggerOptions {
|
|
// The size of this structure, used for versioning.
|
|
uint32_t struct_size;
|
|
|
|
// Flags. Currently unused.
|
|
MojoAddTriggerFlags flags;
|
|
};
|
|
MOJO_STATIC_ASSERT(sizeof(MojoAddTriggerOptions) == 8,
|
|
"MojoAddTriggerOptions has wrong size.");
|
|
|
|
// Flags passed to |MojoRemoveTrigger()| via |MojoRemoveTriggerOptions|.
|
|
typedef uint32_t MojoRemoveTriggerFlags;
|
|
|
|
#ifdef __cplusplus
|
|
const MojoRemoveTriggerFlags MOJO_REMOVE_TRIGGER_FLAG_NONE = 0;
|
|
#else
|
|
#define MOJO_REMOVE_TRIGGER_FLAG_NONE ((MojoRemoveTriggerFlags)0)
|
|
#endif
|
|
|
|
// Options passed to |MojoRemoveTrigger()|.
|
|
struct MOJO_ALIGNAS(8) MojoRemoveTriggerOptions {
|
|
// The size of this structure, used for versioning.
|
|
uint32_t struct_size;
|
|
|
|
// Flags. Currently unused.
|
|
MojoRemoveTriggerFlags flags;
|
|
};
|
|
MOJO_STATIC_ASSERT(sizeof(MojoRemoveTriggerOptions) == 8,
|
|
"MojoRemoveTriggerOptions has wrong size.");
|
|
|
|
// Flags passed to |MojoArmTrap()| via |MojoArmTrapOptions|.
|
|
typedef uint32_t MojoArmTrapFlags;
|
|
|
|
#ifdef __cplusplus
|
|
const MojoArmTrapFlags MOJO_ARM_TRAP_FLAG_NONE = 0;
|
|
#else
|
|
#define MOJO_ARM_TRAP_FLAG_NONE ((MojoArmTrapFlags)0)
|
|
#endif
|
|
|
|
// Options passed to |MojoArmTrap()|.
|
|
struct MOJO_ALIGNAS(8) MojoArmTrapOptions {
|
|
// The size of this structure, used for versioning.
|
|
uint32_t struct_size;
|
|
|
|
// Flags. Currently unused.
|
|
MojoArmTrapFlags flags;
|
|
};
|
|
MOJO_STATIC_ASSERT(sizeof(MojoArmTrapOptions) == 8,
|
|
"MojoArmTrapOptions has wrong size.");
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
// A user-provided callback to handle trap events. Passed to |MojoCreateTrap()|.
|
|
typedef void (*MojoTrapEventHandler)(const struct MojoTrapEvent* event);
|
|
|
|
// Creates a new trap which can be used to detect signal changes on a handle.
|
|
// Traps execute arbitrary user code when tripped.
|
|
//
|
|
// Traps can trip only while armed**, and new traps are created in a disarmed
|
|
// state. Traps may be armed using |MojoArmTrap()|.
|
|
//
|
|
// Arming a trap is only possible when the trap has one or more triggers
|
|
// attached to it. Triggers can be added or removed using |MojoAddTrigger()| and
|
|
// |MojoRemoveTrigger()|.
|
|
//
|
|
// If a trap is tripped by any of its triggers, it is disarmed immediately and
|
|
// the traps |MojoTrapEventHandler| is invoked once for every relevant trigger.
|
|
//
|
|
// |options| may be null.
|
|
//
|
|
// ** An unarmed trap will still fire an event when a trigger is removed. This
|
|
// event will always convey the result |MOJO_RESULT_CANCELLED|.
|
|
//
|
|
// Parameters:
|
|
// |handler|: The |MojoTrapEventHandler| to invoke any time this trap is
|
|
// tripped. Note that this may be called from any arbitrary thread.
|
|
// |trap_handle|: The address at which to store the MojoHandle corresponding
|
|
// to the new trap if successfully created.
|
|
//
|
|
// Returns:
|
|
// |MOJO_RESULT_OK| if the trap has been successfully created.
|
|
// |MOJO_RESULT_RESOURCE_EXHAUSTED| if a handle could not be allocated for
|
|
// this trap.
|
|
MOJO_SYSTEM_EXPORT MojoResult
|
|
MojoCreateTrap(MojoTrapEventHandler handler,
|
|
const struct MojoCreateTrapOptions* options,
|
|
MojoHandle* trap_handle);
|
|
|
|
// Adds a trigger to a trap. This configures the trap to invoke its event
|
|
// handler if the specified conditions are met (or can no longer be met) while
|
|
// the trap is armed.
|
|
//
|
|
// Note that event handler invocations for a given trigger are mutually
|
|
// exclusive in execution: the handler will never be entered for a trigger while
|
|
// another thread is executing it for the same trigger. Similarly, event
|
|
// handlers are never re-entered. If an event handler changes the state of the
|
|
// system such that another event would fire, that event is deferred until the
|
|
// first handler returns.
|
|
//
|
|
// Parameters:
|
|
// |trap_handle|: The trap to which this trigger is to be added.
|
|
// |handle|: The handle whose signals this trigger will observe. Must be a
|
|
// message pipe or data pipe handle.
|
|
// |signals|: The specific signal(s) this trigger will observe on |handle|.
|
|
// |condition|: The signaling condition this trigger will observe. i.e.
|
|
// whether to trip the trap when |signals| become satisfied or when they
|
|
// become unsatisfied.
|
|
// |context|: An arbitrary context value to be passed to the trap's event
|
|
// handler when this trigger was responsible for tripping the trap. See
|
|
// the |trigger_context| field in |MojoTrapEvent|. This value must be
|
|
// unique among all triggers on the trap.
|
|
//
|
|
// |options| may be null.
|
|
//
|
|
// Returns:
|
|
// |MOJO_RESULT_OK| if the handle is now being observed by the trigger.
|
|
// |MOJO_RESULT_INVALID_ARGUMENT| if |trap_handle| is not a trap handle,
|
|
// |handle| is not a valid message pipe or data pipe handle, or |signals|
|
|
// or |condition| are an invalid value.
|
|
// |MOJO_RESULT_ALREADY_EXISTS| if the trap already has a trigger associated
|
|
// with |context| or |handle|.
|
|
MOJO_SYSTEM_EXPORT MojoResult
|
|
MojoAddTrigger(MojoHandle trap_handle,
|
|
MojoHandle handle,
|
|
MojoHandleSignals signals,
|
|
MojoTriggerCondition condition,
|
|
uintptr_t context,
|
|
const struct MojoAddTriggerOptions* options);
|
|
|
|
// Removes a trigger from a trap.
|
|
//
|
|
// This ensures that the trigger is removed as soon as possible. Removal may
|
|
// block an arbitrarily long time if the trap is already executing its handler.
|
|
//
|
|
// When removal is complete, the trap's handler is invoked one final time for
|
|
// time for |context|, with the result |MOJO_RESULT_CANCELLED|.
|
|
//
|
|
// The same behavior can be elicted by either closing the watched handle
|
|
// associated with this trigger, or by closing |trap_handle| itself.
|
|
//
|
|
// Parameters:
|
|
// |trap_handle|: The handle of the trap from which to remove a trigger.
|
|
// |context|: The context of the trigger to be removed.
|
|
//
|
|
// Returns:
|
|
// |MOJO_RESULT_OK| if the trigger has been removed.
|
|
// |MOJO_RESULT_INVALID_ARGUMENT| if |trap_handle| is not a trap handle.
|
|
// |MOJO_RESULT_NOT_FOUND| if there is no trigger registered on this trap for
|
|
// the given value of |context|.
|
|
MOJO_SYSTEM_EXPORT MojoResult
|
|
MojoRemoveTrigger(MojoHandle trap_handle,
|
|
uintptr_t context,
|
|
const struct MojoRemoveTriggerOptions* options);
|
|
|
|
// Arms a trap, allowing it to invoke its event handler the next time any of its
|
|
// triggers' conditions are met.
|
|
//
|
|
// Parameters:
|
|
// |trap_handle|: The handle of the trap to be armed.
|
|
// |num_blocking_events|: An address pointing to the number of elements
|
|
// available for storage at the address given by |blocking_events|.
|
|
// Optional and only used when |MOJO_RESULT_FAILED_PRECONDITION| is
|
|
// returned. See below.
|
|
// |blocking_events|: An output buffer for |MojoTrapEvent| structures to be
|
|
// filled in if one or more triggers would have tripped the trap
|
|
// immediately if it were armed. Optional and used only when
|
|
// |MOJO_RESULT_FAILED_PRECONDITION| is returned. See below.
|
|
//
|
|
// Returns:
|
|
// |MOJO_RESULT_OK| if the trap has been successfully armed.
|
|
// |num_blocking_events| and |blocking_events| are ignored.
|
|
// |MOJO_RESULT_NOT_FOUND| if the trap does not have any triggers.
|
|
// |num_blocking_events| and |blocking_events| are ignored.
|
|
// |MOJO_RESULT_INVALID_ARGUMENT| if |trap_handle| is not a valid trap handle,
|
|
// or if |num_blocking_events| is non-null but |blocking_events| is
|
|
// not.
|
|
// |MOJO_RESULT_FAILED_PRECONDITION| if one or more triggers would have
|
|
// tripped the trap immediately upon arming. If |num_blocking_events| is
|
|
// non-null, this assumes there is enough space for |*num_blocking_events|
|
|
// entries at the non-null address in |blocking_events|.
|
|
//
|
|
// At most |*num_blocking_events| entries are populated there, with each
|
|
// entry corresponding to one of the triggers which would have tripped the
|
|
// trap. The actual number of entries populated is written to
|
|
// |*num_blocking_events| before returning.
|
|
//
|
|
// If there are more ready triggers than available provided storage, the
|
|
// subset presented to the caller is arbitrary. The runtime makes an
|
|
// effort to circulate triggers returned by consecutive failed
|
|
// |MojoArmTrap()| calls so that callers may avoid handle starvation when
|
|
// observing a large number of active handles with a single trap.
|
|
MOJO_SYSTEM_EXPORT MojoResult
|
|
MojoArmTrap(MojoHandle trap_handle,
|
|
const struct MojoArmTrapOptions* options,
|
|
uint32_t* num_blocking_events,
|
|
struct MojoTrapEvent* blocking_events);
|
|
|
|
#ifdef __cplusplus
|
|
} // extern "C"
|
|
#endif
|
|
|
|
#endif // MOJO_PUBLIC_C_SYSTEM_TRAP_H_
|