source: mainline/uspace/lib/c/generic/ns.c@ 28a5ebd

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 28a5ebd 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: 5.6 KB
Line 
1/*
2 * Copyright (c) 2011 Martin Decky
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#include <ns.h>
36#include <ipc/ns.h>
37#include <async.h>
38#include <macros.h>
39#include <errno.h>
40#include "private/ns.h"
41
42/*
43 * XXX ns does not know about session_ns, so we create an extra session for
44 * actual communicaton
45 */
46static async_sess_t *sess_ns = NULL;
47
48errno_t service_register(service_t service, iface_t iface,
49 async_port_handler_t handler, void *data)
50{
51 errno_t rc;
52 async_sess_t *sess = ns_session_get(&rc);
53 if (sess == NULL)
54 return rc;
55
56 port_id_t port;
57 rc = async_create_port(iface, handler, data, &port);
58 if (rc != EOK)
59 return rc;
60
61 async_exch_t *exch = async_exchange_begin(sess);
62
63 ipc_call_t answer;
64 aid_t req = async_send_2(exch, NS_REGISTER, service, iface, &answer);
65 rc = async_connect_to_me(exch, iface, service, 0);
66
67 async_exchange_end(exch);
68
69 if (rc != EOK) {
70 async_forget(req);
71 return rc;
72 }
73
74 errno_t retval;
75 async_wait_for(req, &retval);
76 return rc;
77}
78
79errno_t service_register_broker(service_t service, async_port_handler_t handler,
80 void *data)
81{
82 async_set_fallback_port_handler(handler, data);
83
84 errno_t rc;
85 async_sess_t *sess = ns_session_get(&rc);
86 if (sess == NULL)
87 return rc;
88
89 async_exch_t *exch = async_exchange_begin(sess);
90
91 ipc_call_t answer;
92 aid_t req = async_send_1(exch, NS_REGISTER_BROKER, service, &answer);
93 rc = async_connect_to_me(exch, INTERFACE_ANY, service, 0);
94
95 async_exchange_end(exch);
96
97 if (rc != EOK) {
98 async_forget(req);
99 return rc;
100 }
101
102 errno_t retval;
103 async_wait_for(req, &retval);
104 return rc;
105}
106
107/** Connect to a singleton service.
108 *
109 * @param service Singleton service ID.
110 * @param iface Interface to connect to.
111 * @param arg3 Custom connection argument.
112 * @param rc Placeholder for return code. Unused if NULL.
113 *
114 * @return New session on success or NULL on error.
115 *
116 */
117async_sess_t *service_connect(service_t service, iface_t iface, sysarg_t arg3,
118 errno_t *rc)
119{
120 async_sess_t *sess = ns_session_get(rc);
121 if (sess == NULL)
122 return NULL;
123
124 async_exch_t *exch = async_exchange_begin(sess);
125 if (exch == NULL)
126 return NULL;
127
128 async_sess_t *csess =
129 async_connect_me_to(exch, iface, service, arg3, rc);
130 async_exchange_end(exch);
131
132 if (csess == NULL)
133 return NULL;
134
135 /*
136 * FIXME Ugly hack to work around limitation of implementing
137 * parallel exchanges using multiple connections. Shift out
138 * first argument for non-initial connections.
139 */
140 async_sess_args_set(csess, iface, arg3, 0);
141
142 return csess;
143}
144
145/** Wait and connect to a singleton service.
146 *
147 * @param service Singleton service ID.
148 * @param iface Interface to connect to.
149 * @param arg3 Custom connection argument.
150 * @param rc Placeholder for return code. Unused if NULL.
151 *
152 * @return New session on success or NULL on error.
153 *
154 */
155async_sess_t *service_connect_blocking(service_t service, iface_t iface,
156 sysarg_t arg3, errno_t *rc)
157{
158 async_sess_t *sess = ns_session_get(rc);
159 if (sess == NULL)
160 return NULL;
161
162 async_exch_t *exch = async_exchange_begin(sess);
163 async_sess_t *csess =
164 async_connect_me_to_blocking(exch, iface, service, arg3, rc);
165 async_exchange_end(exch);
166
167 if (csess == NULL)
168 return NULL;
169
170 /*
171 * FIXME Ugly hack to work around limitation of implementing
172 * parallel exchanges using multiple connections. Shift out
173 * first argument for non-initial connections.
174 */
175 async_sess_args_set(csess, iface, arg3, 0);
176
177 return csess;
178}
179
180errno_t ns_ping(void)
181{
182 errno_t rc;
183 async_sess_t *sess = ns_session_get(&rc);
184 if (sess == NULL)
185 return rc;
186
187 async_exch_t *exch = async_exchange_begin(sess);
188 rc = async_req_0_0(exch, NS_PING);
189 async_exchange_end(exch);
190
191 return rc;
192}
193
194errno_t ns_intro(task_id_t id)
195{
196 errno_t rc;
197 async_sess_t *sess = ns_session_get(&rc);
198 if (sess == NULL)
199 return EIO;
200
201 async_exch_t *exch = async_exchange_begin(sess);
202 rc = async_req_2_0(exch, NS_ID_INTRO, LOWER32(id), UPPER32(id));
203 async_exchange_end(exch);
204
205 return rc;
206}
207
208async_sess_t *ns_session_get(errno_t *rc)
209{
210 async_exch_t *exch;
211
212 if (sess_ns == NULL) {
213 exch = async_exchange_begin(&session_ns);
214 sess_ns = async_connect_me_to(exch, 0, 0, 0, rc);
215 async_exchange_end(exch);
216 if (sess_ns == NULL)
217 return NULL;
218 }
219
220 return sess_ns;
221}
222
223/** @}
224 */
Note: See TracBrowser for help on using the repository browser.