source: mainline/uspace/lib/c/include/async.h@ 01900b6

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 01900b6 was 01900b6, checked in by Martin Decky <martin@…>, 5 years ago

Use an optional output argument instead of errno to propagate the error

The use of errno is troublesome in all other than top-level library
functions since the value in errno might get overwritten by subsequent
inner calls on the error path (e.g. cleanup, deallocation, etc.). The
optional output argument makes it possible to explicitly ignore the
error code if it is not needed, but still to pass it reliably back to
the original caller.

This change affecs async_connect_me_to(),
async_connect_me_to_blocking(), async_connect_kbox(), service_connect(),
service_connect_blocking() and loader_connect().

  • Property mode set to 100644
File size: 16.0 KB
Line 
1/*
2 * Copyright (c) 2006 Ondrej Palkovsky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libc
30 * @{
31 */
32/** @file
33 */
34
35#if ((defined(_LIBC_IPC_H_)) && (!defined(_LIBC_ASYNC_C_)))
36#error Do not intermix low-level IPC interface and async framework
37#endif
38
39#ifndef _LIBC_ASYNC_H_
40#define _LIBC_ASYNC_H_
41
42#include <ipc/common.h>
43#include <time.h>
44#include <stdbool.h>
45#include <abi/proc/task.h>
46#include <abi/ddi/irq.h>
47#include <abi/ipc/event.h>
48#include <abi/ipc/interfaces.h>
49#include <abi/cap.h>
50
51#include <_bits/__noreturn.h>
52
53typedef sysarg_t aid_t;
54typedef sysarg_t port_id_t;
55
56typedef void *(*async_client_data_ctor_t)(void);
57typedef void (*async_client_data_dtor_t)(void *);
58
59/** Port connection handler
60 *
61 * @param call Incoming call or NULL if connection initiated from inside
62 * using async_create_callback_port()
63 * @param arg Local argument.
64 *
65 */
66typedef void (*async_port_handler_t)(ipc_call_t *, void *);
67
68/** Notification handler */
69typedef void (*async_notification_handler_t)(ipc_call_t *, void *);
70
71/** Exchange management style
72 *
73 */
74typedef enum {
75 /** No explicit exchange management
76 *
77 * Suitable for protocols which use a single
78 * IPC message per exchange only.
79 *
80 */
81 EXCHANGE_ATOMIC = 0,
82
83 /** Exchange management via mutual exclusion
84 *
85 * Suitable for any kind of client/server communication,
86 * but can limit parallelism.
87 *
88 */
89 EXCHANGE_SERIALIZE = 1,
90
91 /** Exchange management via phone cloning
92 *
93 * Suitable for servers which support client
94 * data tracking by task hashes and do not
95 * mind cloned phones.
96 *
97 */
98 EXCHANGE_PARALLEL = 2
99} exch_mgmt_t;
100
101/** Forward declarations */
102struct async_exch;
103struct async_sess;
104
105typedef struct async_sess async_sess_t;
106typedef struct async_exch async_exch_t;
107
108extern __noreturn void async_manager(void);
109
110extern bool async_get_call(ipc_call_t *);
111extern bool async_get_call_timeout(ipc_call_t *, usec_t);
112
113extern aid_t async_send_0(async_exch_t *, sysarg_t, ipc_call_t *);
114extern aid_t async_send_1(async_exch_t *, sysarg_t, sysarg_t, ipc_call_t *);
115extern aid_t async_send_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
116 ipc_call_t *);
117extern aid_t async_send_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
118 sysarg_t, ipc_call_t *);
119extern aid_t async_send_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
120 sysarg_t, sysarg_t, ipc_call_t *);
121extern aid_t async_send_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
122 sysarg_t, sysarg_t, sysarg_t, ipc_call_t *);
123
124extern void async_wait_for(aid_t, errno_t *);
125extern errno_t async_wait_timeout(aid_t, errno_t *, usec_t);
126extern void async_forget(aid_t);
127
128extern void async_set_client_data_constructor(async_client_data_ctor_t);
129extern void async_set_client_data_destructor(async_client_data_dtor_t);
130extern void *async_get_client_data(void);
131extern void *async_get_client_data_by_id(task_id_t);
132extern void async_put_client_data_by_id(task_id_t);
133
134extern errno_t async_create_port(iface_t, async_port_handler_t, void *,
135 port_id_t *);
136extern void async_set_fallback_port_handler(async_port_handler_t, void *);
137extern errno_t async_create_callback_port(async_exch_t *, iface_t, sysarg_t,
138 sysarg_t, async_port_handler_t, void *, port_id_t *);
139
140extern errno_t async_irq_subscribe(int, async_notification_handler_t, void *,
141 const irq_code_t *, cap_irq_handle_t *);
142extern errno_t async_irq_unsubscribe(cap_irq_handle_t);
143
144extern errno_t async_event_subscribe(event_type_t, async_notification_handler_t,
145 void *);
146extern errno_t async_event_task_subscribe(event_task_type_t,
147 async_notification_handler_t, void *);
148extern errno_t async_event_unsubscribe(event_type_t);
149extern errno_t async_event_task_unsubscribe(event_task_type_t);
150extern errno_t async_event_unmask(event_type_t);
151extern errno_t async_event_task_unmask(event_task_type_t);
152
153/*
154 * Wrappers for simple communication.
155 */
156
157extern void async_msg_0(async_exch_t *, sysarg_t);
158extern void async_msg_1(async_exch_t *, sysarg_t, sysarg_t);
159extern void async_msg_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t);
160extern void async_msg_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t);
161extern void async_msg_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
162 sysarg_t);
163extern void async_msg_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
164 sysarg_t, sysarg_t);
165
166/*
167 * Wrappers for answer routines.
168 */
169
170extern errno_t async_answer_0(ipc_call_t *, errno_t);
171extern errno_t async_answer_1(ipc_call_t *, errno_t, sysarg_t);
172extern errno_t async_answer_2(ipc_call_t *, errno_t, sysarg_t, sysarg_t);
173extern errno_t async_answer_3(ipc_call_t *, errno_t, sysarg_t, sysarg_t,
174 sysarg_t);
175extern errno_t async_answer_4(ipc_call_t *, errno_t, sysarg_t, sysarg_t,
176 sysarg_t, sysarg_t);
177extern errno_t async_answer_5(ipc_call_t *, errno_t, sysarg_t, sysarg_t,
178 sysarg_t, sysarg_t, sysarg_t);
179
180/*
181 * Wrappers for forwarding routines.
182 */
183
184extern errno_t async_forward_0(ipc_call_t *, async_exch_t *, sysarg_t,
185 unsigned int);
186extern errno_t async_forward_1(ipc_call_t *, async_exch_t *, sysarg_t,
187 sysarg_t, unsigned int);
188extern errno_t async_forward_2(ipc_call_t *, async_exch_t *, sysarg_t,
189 sysarg_t, sysarg_t, unsigned int);
190extern errno_t async_forward_3(ipc_call_t *, async_exch_t *, sysarg_t,
191 sysarg_t, sysarg_t, sysarg_t, unsigned int);
192extern errno_t async_forward_4(ipc_call_t *, async_exch_t *, sysarg_t,
193 sysarg_t, sysarg_t, sysarg_t, sysarg_t, unsigned int);
194extern errno_t async_forward_5(ipc_call_t *, async_exch_t *, sysarg_t,
195 sysarg_t, sysarg_t, sysarg_t, sysarg_t, sysarg_t, unsigned int);
196
197/*
198 * User-friendly wrappers for async_req_*_*().
199 * The functions are in the form async_req_m_n(), where m is the number of
200 * payload arguments and n is the number of return arguments.
201 */
202
203extern errno_t async_req_0_0(async_exch_t *, sysarg_t);
204extern errno_t async_req_0_1(async_exch_t *, sysarg_t, sysarg_t *);
205extern errno_t async_req_0_2(async_exch_t *, sysarg_t, sysarg_t *, sysarg_t *);
206extern errno_t async_req_0_3(async_exch_t *, sysarg_t, sysarg_t *, sysarg_t *,
207 sysarg_t *);
208extern errno_t async_req_0_4(async_exch_t *, sysarg_t, sysarg_t *, sysarg_t *,
209 sysarg_t *, sysarg_t *);
210extern errno_t async_req_0_5(async_exch_t *, sysarg_t, sysarg_t *, sysarg_t *,
211 sysarg_t *, sysarg_t *, sysarg_t *);
212extern errno_t async_req_1_0(async_exch_t *, sysarg_t, sysarg_t);
213extern errno_t async_req_1_1(async_exch_t *, sysarg_t, sysarg_t, sysarg_t *);
214extern errno_t async_req_1_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t *,
215 sysarg_t *);
216extern errno_t async_req_1_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t *,
217 sysarg_t *, sysarg_t *);
218extern errno_t async_req_1_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t *,
219 sysarg_t *, sysarg_t *, sysarg_t *);
220extern errno_t async_req_1_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t *,
221 sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
222extern errno_t async_req_2_0(async_exch_t *, sysarg_t, sysarg_t, sysarg_t);
223extern errno_t async_req_2_1(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
224 sysarg_t *);
225extern errno_t async_req_2_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
226 sysarg_t *, sysarg_t *);
227extern errno_t async_req_2_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
228 sysarg_t *, sysarg_t *, sysarg_t *);
229extern errno_t async_req_2_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
230 sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
231extern errno_t async_req_2_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
232 sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
233extern errno_t async_req_3_0(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
234 sysarg_t);
235extern errno_t async_req_3_1(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
236 sysarg_t, sysarg_t *);
237extern errno_t async_req_3_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
238 sysarg_t, sysarg_t *, sysarg_t *);
239extern errno_t async_req_3_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
240 sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *);
241extern errno_t async_req_3_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
242 sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
243extern errno_t async_req_3_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
244 sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
245extern errno_t async_req_4_0(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
246 sysarg_t, sysarg_t);
247extern errno_t async_req_4_1(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
248 sysarg_t, sysarg_t, sysarg_t *);
249extern errno_t async_req_4_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
250 sysarg_t, sysarg_t, sysarg_t *, sysarg_t *);
251extern errno_t async_req_4_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
252 sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *);
253extern errno_t async_req_4_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
254 sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
255extern errno_t async_req_4_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
256 sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *,
257 sysarg_t *);
258extern errno_t async_req_5_0(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
259 sysarg_t, sysarg_t, sysarg_t);
260extern errno_t async_req_5_1(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
261 sysarg_t, sysarg_t, sysarg_t, sysarg_t *);
262extern errno_t async_req_5_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
263 sysarg_t, sysarg_t, sysarg_t, sysarg_t *, sysarg_t *);
264extern errno_t async_req_5_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
265 sysarg_t, sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *);
266extern errno_t async_req_5_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
267 sysarg_t, sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *,
268 sysarg_t *);
269extern errno_t async_req_5_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
270 sysarg_t, sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *,
271 sysarg_t *, sysarg_t *);
272
273extern errno_t async_accept_0(ipc_call_t *);
274extern sysarg_t async_get_label(void);
275
276extern async_sess_t *async_connect_me_to(async_exch_t *, iface_t, sysarg_t,
277 sysarg_t, errno_t *);
278extern async_sess_t *async_connect_me_to_blocking(async_exch_t *, iface_t,
279 sysarg_t, sysarg_t, errno_t *);
280extern async_sess_t *async_connect_kbox(task_id_t, errno_t *);
281
282extern errno_t async_connect_to_me(async_exch_t *, iface_t, sysarg_t, sysarg_t);
283
284extern errno_t async_hangup(async_sess_t *);
285
286extern async_exch_t *async_exchange_begin(async_sess_t *);
287extern void async_exchange_end(async_exch_t *);
288
289/*
290 * FIXME These functions just work around problems with parallel exchange
291 * management. Proper solution needs to be implemented.
292 */
293extern void async_sess_args_set(async_sess_t *, iface_t, sysarg_t, sysarg_t);
294
295/*
296 * User-friendly wrappers for async_share_in_start().
297 */
298
299extern errno_t async_share_in_start_0_0(async_exch_t *, size_t, void **);
300extern errno_t async_share_in_start_0_1(async_exch_t *, size_t,
301 unsigned int *, void **);
302extern errno_t async_share_in_start_1_0(async_exch_t *, size_t, sysarg_t,
303 void **);
304extern errno_t async_share_in_start_1_1(async_exch_t *, size_t, sysarg_t,
305 unsigned int *, void **);
306
307extern bool async_share_in_receive(ipc_call_t *, size_t *);
308extern errno_t async_share_in_finalize(ipc_call_t *, void *, unsigned int);
309
310extern errno_t async_share_out_start(async_exch_t *, void *, unsigned int);
311extern bool async_share_out_receive(ipc_call_t *, size_t *, unsigned int *);
312extern errno_t async_share_out_finalize(ipc_call_t *, void **);
313
314extern errno_t async_data_read_forward_0_0(async_exch_t *, sysarg_t);
315extern errno_t async_data_read_forward_1_0(async_exch_t *, sysarg_t, sysarg_t);
316extern errno_t async_data_read_forward_2_0(async_exch_t *, sysarg_t, sysarg_t,
317 sysarg_t);
318extern errno_t async_data_read_forward_3_0(async_exch_t *, sysarg_t, sysarg_t,
319 sysarg_t, sysarg_t);
320extern errno_t async_data_read_forward_4_0(async_exch_t *, sysarg_t, sysarg_t,
321 sysarg_t, sysarg_t, sysarg_t);
322
323extern errno_t async_data_read_forward_0_1(async_exch_t *, sysarg_t,
324 ipc_call_t *);
325extern errno_t async_data_read_forward_1_1(async_exch_t *, sysarg_t, sysarg_t,
326 ipc_call_t *);
327extern errno_t async_data_read_forward_2_1(async_exch_t *, sysarg_t, sysarg_t,
328 sysarg_t, ipc_call_t *);
329extern errno_t async_data_read_forward_3_1(async_exch_t *, sysarg_t, sysarg_t,
330 sysarg_t, sysarg_t, ipc_call_t *);
331extern errno_t async_data_read_forward_4_1(async_exch_t *, sysarg_t, sysarg_t,
332 sysarg_t, sysarg_t, sysarg_t, ipc_call_t *);
333
334extern aid_t async_data_read(async_exch_t *, void *, size_t, ipc_call_t *);
335extern errno_t async_data_read_start(async_exch_t *, void *, size_t);
336extern bool async_data_read_receive(ipc_call_t *, size_t *);
337extern errno_t async_data_read_finalize(ipc_call_t *, const void *, size_t);
338
339extern errno_t async_data_write_forward_0_0(async_exch_t *, sysarg_t);
340extern errno_t async_data_write_forward_1_0(async_exch_t *, sysarg_t, sysarg_t);
341extern errno_t async_data_write_forward_2_0(async_exch_t *, sysarg_t, sysarg_t,
342 sysarg_t);
343extern errno_t async_data_write_forward_3_0(async_exch_t *, sysarg_t, sysarg_t,
344 sysarg_t, sysarg_t);
345extern errno_t async_data_write_forward_4_0(async_exch_t *, sysarg_t, sysarg_t,
346 sysarg_t, sysarg_t, sysarg_t);
347
348extern errno_t async_data_write_forward_0_1(async_exch_t *, sysarg_t,
349 ipc_call_t *);
350extern errno_t async_data_write_forward_1_1(async_exch_t *, sysarg_t, sysarg_t,
351 ipc_call_t *);
352extern errno_t async_data_write_forward_2_1(async_exch_t *, sysarg_t, sysarg_t,
353 sysarg_t, ipc_call_t *);
354extern errno_t async_data_write_forward_3_1(async_exch_t *, sysarg_t, sysarg_t,
355 sysarg_t, sysarg_t, ipc_call_t *);
356extern errno_t async_data_write_forward_4_1(async_exch_t *, sysarg_t, sysarg_t,
357 sysarg_t, sysarg_t, sysarg_t, ipc_call_t *);
358
359extern errno_t async_data_write_start(async_exch_t *, const void *, size_t);
360extern bool async_data_write_receive(ipc_call_t *, size_t *);
361extern errno_t async_data_write_finalize(ipc_call_t *, void *, size_t);
362
363extern errno_t async_data_write_accept(void **, const bool, const size_t,
364 const size_t, const size_t, size_t *);
365extern void async_data_write_void(errno_t);
366
367extern async_sess_t *async_callback_receive(exch_mgmt_t);
368extern async_sess_t *async_callback_receive_start(exch_mgmt_t, ipc_call_t *);
369
370extern errno_t async_state_change_start(async_exch_t *, sysarg_t, sysarg_t,
371 sysarg_t, async_exch_t *);
372extern bool async_state_change_receive(ipc_call_t *);
373extern errno_t async_state_change_finalize(ipc_call_t *, async_exch_t *);
374
375extern void *async_remote_state_acquire(async_sess_t *);
376extern void async_remote_state_update(async_sess_t *, void *);
377extern void async_remote_state_release(async_sess_t *);
378extern void async_remote_state_release_exchange(async_exch_t *);
379
380extern void *async_as_area_create(void *, size_t, unsigned int, async_sess_t *,
381 sysarg_t, sysarg_t, sysarg_t);
382
383errno_t async_spawn_notification_handler(void);
384
385#endif
386
387/** @}
388 */
Note: See TracBrowser for help on using the repository browser.