• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 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 #ifndef MOJO_PUBLIC_C_SYSTEM_TRAP_H_
6 #define MOJO_PUBLIC_C_SYSTEM_TRAP_H_
7 
8 #include <stdint.h>
9 
10 #include "mojo/public/c/system/macros.h"
11 #include "mojo/public/c/system/system_export.h"
12 #include "mojo/public/c/system/types.h"
13 
14 // Flags passed to trap event handlers within |MojoTrapEvent|.
15 typedef uint32_t MojoTrapEventFlags;
16 
17 #ifdef __cplusplus
18 const MojoTrapEventFlags MOJO_TRAP_EVENT_FLAG_NONE = 0;
19 const MojoTrapEventFlags MOJO_TRAP_EVENT_FLAG_WITHIN_API_CALL = 1 << 0;
20 #else
21 #define MOJO_TRAP_EVENT_FLAG_NONE ((MojoTrapEventFlags)0)
22 #define MOJO_TRAP_EVENT_FLAG_WITHIN_API_CALL ((MojoTrapEventFlags)1 << 0)
23 #endif
24 
25 // Structure passed to trap event handlers when invoked by a tripped trap.
26 struct MOJO_ALIGNAS(8) MojoTrapEvent {
27   // The size of this structure, used for versioning.
28   uint32_t struct_size;
29 
30   // May take on some combination of the following values:
31   //
32   //   |MOJO_TRAP_EVENT_FLAG_NONE|: No flags.
33   //
34   //   |MOJO_TRAP_EVENT_FLAG_WITHIN_API_CALL|: The trap was tripped within the
35   //       extent of a user call to some Mojo API. This means that the event
36   //       handler itself is re-entering user code. May happen, for example, if
37   //       user code writes to an intra-process pipe and the receiving end trips
38   //       a trap as a result. In that case the event handler executes within
39   //       the extent of the |MojoWriteMessage()| call.
40   MojoTrapEventFlags flags;
41 
42   // The context for the trigger which tripped the trap.
43   MOJO_POINTER_FIELD(uintptr_t, trigger_context);
44 
45   // A result code indicating the cause of the event. May take on any of the
46   // following values:
47   //
48   //   |MOJO_RESULT_OK|: The trigger's conditions were met.
49   //   |MOJO_RESULT_FAILED_PRECONDITION|: The trigger's observed handle has
50   //       changed state in such a way that the trigger's conditions can never
51   //       be met again.
52   //   |MOJO_RESULT_CANCELLED|: The trigger has been removed and will never
53   //       cause another event to fire. This is always the last event fired by
54   //       a trigger and it will fire when: the trigger is explicitly removed
55   //       with |MojoRemoteTrigger()|, the trigger's owning trap handle is
56   //       closed, or the handle observed by the trigger is closed.
57   //
58   //       Unlike the other result types above |MOJO_RESULT_CANCELLED| can
59   //       fire even when the trap is disarmed.
60   MojoResult result;
61 
62   // The last known signalling state of the trigger's observed handle at the
63   // time the trap was tripped.
64   struct MojoHandleSignalsState signals_state;
65 };
66 MOJO_STATIC_ASSERT(sizeof(MojoTrapEvent) == 32,
67                    "MojoTrapEvent has wrong size.");
68 
69 // Value given to |MojoAddTrigger| to configure what condition should cause it
70 // to trip its trap. May be one of the following values:
71 //
72 //   |MOJO_TRIGGER_CONDITION_SIGNALS_UNSATISFIED| - A trigger added with this
73 //       condition will trip its trap when any of its observed signals
74 //       transition from being satisfied to being unsatisfied.
75 //   |MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED| - A triger added with this
76 //       condition will trip its trap  when any of its observed signals
77 //       transition from being unsatisfied to being satisfied, or when none of
78 //       the observed signals can ever be satisfied again.
79 typedef uint32_t MojoTriggerCondition;
80 
81 #ifdef __cplusplus
82 const MojoTriggerCondition MOJO_TRIGGER_CONDITION_SIGNALS_UNSATISFIED = 0;
83 const MojoTriggerCondition MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED = 1;
84 #else
85 #define MOJO_TRIGGER_CONDITION_SIGNALS_UNSATISFIED ((MojoTriggerCondition)0)
86 #define MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED ((MojoTriggerCondition)1)
87 #endif
88 
89 // Flags passed to |MojoCreateTrap()| via |MojoCreateTrapOptions|.
90 typedef uint32_t MojoCreateTrapFlags;
91 
92 #ifdef __cplusplus
93 const MojoCreateTrapFlags MOJO_CREATE_TRAP_FLAG_NONE = 0;
94 #else
95 #define MOJO_CREATE_TRAP_FLAG_NONE ((MojoCreateTrapFlags)0)
96 #endif
97 
98 // Options passed to |MojoCreateTrap()|.
99 struct MOJO_ALIGNAS(8) MojoCreateTrapOptions {
100   // The size of this structure, used for versioning.
101   uint32_t struct_size;
102 
103   // Flags. Currently unused.
104   MojoCreateTrapFlags flags;
105 };
106 MOJO_STATIC_ASSERT(sizeof(MojoCreateTrapOptions) == 8,
107                    "MojoCreateTrapOptions has wrong size.");
108 
109 // Flags passed to |MojoAddTrigger()| via |MojoAddTriggerOptions|.
110 typedef uint32_t MojoAddTriggerFlags;
111 
112 #ifdef __cplusplus
113 const MojoAddTriggerFlags MOJO_ADD_TRIGGER_FLAG_NONE = 0;
114 #else
115 #define MOJO_ADD_TRIGGER_FLAG_NONE ((MojoAddTriggerFlags)0)
116 #endif
117 
118 // Options passed to |MojoAddTrigger()|.
119 struct MOJO_ALIGNAS(8) MojoAddTriggerOptions {
120   // The size of this structure, used for versioning.
121   uint32_t struct_size;
122 
123   // Flags. Currently unused.
124   MojoAddTriggerFlags flags;
125 };
126 MOJO_STATIC_ASSERT(sizeof(MojoAddTriggerOptions) == 8,
127                    "MojoAddTriggerOptions has wrong size.");
128 
129 // Flags passed to |MojoRemoveTrigger()| via |MojoRemoveTriggerOptions|.
130 typedef uint32_t MojoRemoveTriggerFlags;
131 
132 #ifdef __cplusplus
133 const MojoRemoveTriggerFlags MOJO_REMOVE_TRIGGER_FLAG_NONE = 0;
134 #else
135 #define MOJO_REMOVE_TRIGGER_FLAG_NONE ((MojoRemoveTriggerFlags)0)
136 #endif
137 
138 // Options passed to |MojoRemoveTrigger()|.
139 struct MOJO_ALIGNAS(8) MojoRemoveTriggerOptions {
140   // The size of this structure, used for versioning.
141   uint32_t struct_size;
142 
143   // Flags. Currently unused.
144   MojoRemoveTriggerFlags flags;
145 };
146 MOJO_STATIC_ASSERT(sizeof(MojoRemoveTriggerOptions) == 8,
147                    "MojoRemoveTriggerOptions has wrong size.");
148 
149 // Flags passed to |MojoArmTrap()| via |MojoArmTrapOptions|.
150 typedef uint32_t MojoArmTrapFlags;
151 
152 #ifdef __cplusplus
153 const MojoArmTrapFlags MOJO_ARM_TRAP_FLAG_NONE = 0;
154 #else
155 #define MOJO_ARM_TRAP_FLAG_NONE ((MojoArmTrapFlags)0)
156 #endif
157 
158 // Options passed to |MojoArmTrap()|.
159 struct MOJO_ALIGNAS(8) MojoArmTrapOptions {
160   // The size of this structure, used for versioning.
161   uint32_t struct_size;
162 
163   // Flags. Currently unused.
164   MojoArmTrapFlags flags;
165 };
166 MOJO_STATIC_ASSERT(sizeof(MojoArmTrapOptions) == 8,
167                    "MojoArmTrapOptions has wrong size.");
168 
169 #ifdef __cplusplus
170 extern "C" {
171 #endif
172 
173 // A user-provided callback to handle trap events. Passed to |MojoCreateTrap()|.
174 typedef void (*MojoTrapEventHandler)(const struct MojoTrapEvent* event);
175 
176 // Creates a new trap which can be used to detect signal changes on a handle.
177 // Traps execute arbitrary user code when tripped.
178 //
179 // Traps can trip only while armed**, and new traps are created in a disarmed
180 // state. Traps may be armed using |MojoArmTrap()|.
181 //
182 // Arming a trap is only possible when the trap has one or more triggers
183 // attached to it. Triggers can be added or removed using |MojoAddTrigger()| and
184 // |MojoRemoveTrigger()|.
185 //
186 // If a trap is tripped by any of its triggers, it is disarmed immediately and
187 // the traps |MojoTrapEventHandler| is invoked once for every relevant trigger.
188 //
189 // |options| may be null.
190 //
191 // ** An unarmed trap will still fire an event when a trigger is removed. This
192 // event will always convey the result |MOJO_RESULT_CANCELLED|.
193 //
194 // Parameters:
195 //   |handler|: The |MojoTrapEventHandler| to invoke any time this trap is
196 //       tripped. Note that this may be called from any arbitrary thread.
197 //   |trap_handle|: The address at which to store the MojoHandle corresponding
198 //       to the new trap if successfully created.
199 //
200 // Returns:
201 //   |MOJO_RESULT_OK| if the trap has been successfully created.
202 //   |MOJO_RESULT_RESOURCE_EXHAUSTED| if a handle could not be allocated for
203 //       this trap.
204 MOJO_SYSTEM_EXPORT MojoResult
205 MojoCreateTrap(MojoTrapEventHandler handler,
206                const struct MojoCreateTrapOptions* options,
207                MojoHandle* trap_handle);
208 
209 // Adds a trigger to a trap. This configures the trap to invoke its event
210 // handler if the specified conditions are met (or can no longer be met) while
211 // the trap is armed.
212 //
213 // Note that event handler invocations for a given trigger are mutually
214 // exclusive in execution: the handler will never be entered for a trigger while
215 // another thread is executing it for the same trigger. Similarly, event
216 // handlers are never re-entered. If an event handler changes the state of the
217 // system such that another event would fire, that event is deferred until the
218 // first handler returns.
219 //
220 // Parameters:
221 //   |trap_handle|: The trap to which this trigger is to be added.
222 //   |handle|: The handle whose signals this trigger will observe. Must be a
223 //       message pipe or data pipe handle.
224 //   |signals|: The specific signal(s) this trigger will observe on |handle|.
225 //   |condition|: The signaling condition this trigger will observe. i.e.
226 //       whether to trip the trap when |signals| become satisfied or when they
227 //       become unsatisfied.
228 //   |context|: An arbitrary context value to be passed to the trap's event
229 //       handler when this trigger was responsible for tripping the trap. See
230 //       the |trigger_context| field in |MojoTrapEvent|. This value must be
231 //       unique among all triggers on the trap.
232 //
233 //   |options| may be null.
234 //
235 // Returns:
236 //   |MOJO_RESULT_OK| if the handle is now being observed by the trigger.
237 //   |MOJO_RESULT_INVALID_ARGUMENT| if |trap_handle| is not a trap handle,
238 //       |handle| is not a valid message pipe or data pipe handle, or |signals|
239 //       or |condition| are an invalid value.
240 //   |MOJO_RESULT_ALREADY_EXISTS| if the trap already has a trigger associated
241 //       with |context| or |handle|.
242 MOJO_SYSTEM_EXPORT MojoResult
243 MojoAddTrigger(MojoHandle trap_handle,
244                MojoHandle handle,
245                MojoHandleSignals signals,
246                MojoTriggerCondition condition,
247                uintptr_t context,
248                const struct MojoAddTriggerOptions* options);
249 
250 // Removes a trigger from a trap.
251 //
252 // This ensures that the trigger is removed as soon as possible. Removal may
253 // block an arbitrarily long time if the trap is already executing its handler.
254 //
255 // When removal is complete, the trap's handler is invoked one final time for
256 // time for |context|, with the result |MOJO_RESULT_CANCELLED|.
257 //
258 // The same  behavior can be elicted by either closing the watched handle
259 // associated with this trigger, or by closing |trap_handle| itself.
260 //
261 // Parameters:
262 //   |trap_handle|: The handle of the trap from which to remove a trigger.
263 //   |context|: The context of the trigger to be removed.
264 //
265 // Returns:
266 //   |MOJO_RESULT_OK| if the trigger has been removed.
267 //   |MOJO_RESULT_INVALID_ARGUMENT| if |trap_handle| is not a trap handle.
268 //   |MOJO_RESULT_NOT_FOUND| if there is no trigger registered on this trap for
269 //       the given value of |context|.
270 MOJO_SYSTEM_EXPORT MojoResult
271 MojoRemoveTrigger(MojoHandle trap_handle,
272                   uintptr_t context,
273                   const struct MojoRemoveTriggerOptions* options);
274 
275 // Arms a trap, allowing it to invoke its event handler the next time any of its
276 // triggers' conditions are met.
277 //
278 // Parameters:
279 //   |trap_handle|: The handle of the trap to be armed.
280 //   |num_blocking_events|: An address pointing to the number of elements
281 //       available for storage at the address given by |blocking_events|.
282 //       Optional and only used when |MOJO_RESULT_FAILED_PRECONDITION| is
283 //       returned. See below.
284 //   |blocking_events|: An output buffer for |MojoTrapEvent| structures to be
285 //       filled in if one or more triggers would have tripped the trap
286 //       immediately if it were armed. Optional and used only when
287 //       |MOJO_RESULT_FAILED_PRECONDITION| is returned. See below.
288 //
289 // Returns:
290 //   |MOJO_RESULT_OK| if the trap has been successfully armed.
291 //       |num_blocking_events| and |blocking_events| are ignored.
292 //   |MOJO_RESULT_NOT_FOUND| if the trap does not have any triggers.
293 //       |num_blocking_events| and |blocking_events| are ignored.
294 //   |MOJO_RESULT_INVALID_ARGUMENT| if |trap_handle| is not a valid trap handle,
295 //       or if |num_blocking_events| is non-null but |blocking_events| is
296 //       not.
297 //   |MOJO_RESULT_FAILED_PRECONDITION| if one or more triggers would have
298 //       tripped the trap immediately upon arming. If |num_blocking_events| is
299 //       non-null, this assumes there is enough space for |*num_blocking_events|
300 //       entries at the non-null address in |blocking_events|.
301 //
302 //       At most |*num_blocking_events| entries are populated there, with each
303 //       entry corresponding to one of the triggers which would have tripped the
304 //       trap. The actual number of entries populated is written to
305 //       |*num_blocking_events| before returning.
306 //
307 //       If there are more ready triggers than available provided storage, the
308 //       subset presented to the caller is arbitrary. The runtime makes an
309 //       effort to circulate triggers returned by consecutive failed
310 //       |MojoArmTrap()| calls so that callers may avoid handle starvation when
311 //       observing a large number of active handles with a single trap.
312 MOJO_SYSTEM_EXPORT MojoResult
313 MojoArmTrap(MojoHandle trap_handle,
314             const struct MojoArmTrapOptions* options,
315             uint32_t* num_blocking_events,
316             struct MojoTrapEvent* blocking_events);
317 
318 #ifdef __cplusplus
319 }  // extern "C"
320 #endif
321 
322 #endif  // MOJO_PUBLIC_C_SYSTEM_TRAP_H_
323