source: mainline/uspace/srv/ns/service.c@ a35b458

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a35b458 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 5.7 KB
Line 
1/*
2 * Copyright (c) 2009 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 ns
30 * @{
31 */
32
33#include <adt/hash_table.h>
34#include <assert.h>
35#include <async.h>
36#include <errno.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include "service.h"
40#include "ns.h"
41
42/** Service hash table item. */
43typedef struct {
44 ht_link_t link;
45
46 /** Service ID */
47 service_t service;
48
49 /** Session to the service */
50 async_sess_t *sess;
51} hashed_service_t;
52
53static size_t service_key_hash(void *key)
54{
55 return *(service_t *) key;
56}
57
58static size_t service_hash(const ht_link_t *item)
59{
60 hashed_service_t *service =
61 hash_table_get_inst(item, hashed_service_t, link);
62
63 return service->service;
64}
65
66static bool service_key_equal(void *key, const ht_link_t *item)
67{
68 hashed_service_t *service =
69 hash_table_get_inst(item, hashed_service_t, link);
70
71 return service->service == *(service_t *) key;
72}
73
74/** Operations for service hash table. */
75static hash_table_ops_t service_hash_table_ops = {
76 .hash = service_hash,
77 .key_hash = service_key_hash,
78 .key_equal = service_key_equal,
79 .equal = NULL,
80 .remove_callback = NULL
81};
82
83/** Service hash table structure. */
84static hash_table_t service_hash_table;
85
86/** Pending connection structure. */
87typedef struct {
88 link_t link;
89 service_t service; /**< Service ID */
90 iface_t iface; /**< Interface ID */
91 ipc_callid_t callid; /**< Call ID waiting for the connection */
92 sysarg_t arg3; /**< Third argument */
93} pending_conn_t;
94
95static list_t pending_conn;
96
97errno_t service_init(void)
98{
99 if (!hash_table_create(&service_hash_table, 0, 0,
100 &service_hash_table_ops)) {
101 printf("%s: No memory available for services\n", NAME);
102 return ENOMEM;
103 }
104
105 list_initialize(&pending_conn);
106
107 return EOK;
108}
109
110/** Process pending connection requests */
111void process_pending_conn(void)
112{
113loop:
114 list_foreach(pending_conn, link, pending_conn_t, pending) {
115 ht_link_t *link = hash_table_find(&service_hash_table, &pending->service);
116 if (!link)
117 continue;
118
119 hashed_service_t *hashed_service = hash_table_get_inst(link, hashed_service_t, link);
120 async_exch_t *exch = async_exchange_begin(hashed_service->sess);
121 async_forward_fast(pending->callid, exch, pending->iface,
122 pending->arg3, 0, IPC_FF_NONE);
123 async_exchange_end(exch);
124
125 list_remove(&pending->link);
126 free(pending);
127
128 goto loop;
129 }
130}
131
132/** Register service.
133 *
134 * @param service Service to be registered.
135 * @param phone Phone to be used for connections to the service.
136 * @param call Pointer to call structure.
137 *
138 * @return Zero on success or a value from @ref errno.h.
139 *
140 */
141errno_t register_service(service_t service, sysarg_t phone, ipc_call_t *call)
142{
143 if (hash_table_find(&service_hash_table, &service))
144 return EEXIST;
145
146 hashed_service_t *hashed_service =
147 (hashed_service_t *) malloc(sizeof(hashed_service_t));
148 if (!hashed_service)
149 return ENOMEM;
150
151 hashed_service->service = service;
152 hashed_service->sess = async_callback_receive(EXCHANGE_SERIALIZE);
153 if (hashed_service->sess == NULL)
154 return EIO;
155
156 hash_table_insert(&service_hash_table, &hashed_service->link);
157 return EOK;
158}
159
160/** Connect client to service.
161 *
162 * @param service Service to be connected to.
163 * @param iface Interface to be connected to.
164 * @param call Pointer to call structure.
165 * @param callid Call ID of the request.
166 *
167 * @return Zero on success or a value from @ref errno.h.
168 *
169 */
170void connect_to_service(service_t service, iface_t iface, ipc_call_t *call,
171 ipc_callid_t callid)
172{
173 sysarg_t arg3 = IPC_GET_ARG3(*call);
174 sysarg_t flags = IPC_GET_ARG4(*call);
175 errno_t retval;
176
177 ht_link_t *link = hash_table_find(&service_hash_table, &service);
178 if (!link) {
179 if (flags & IPC_FLAG_BLOCKING) {
180 /* Blocking connection, add to pending list */
181 pending_conn_t *pending =
182 (pending_conn_t *) malloc(sizeof(pending_conn_t));
183 if (!pending) {
184 retval = ENOMEM;
185 goto out;
186 }
187
188 link_initialize(&pending->link);
189 pending->service = service;
190 pending->iface = iface;
191 pending->callid = callid;
192 pending->arg3 = arg3;
193
194 list_append(&pending->link, &pending_conn);
195 return;
196 }
197
198 retval = ENOENT;
199 goto out;
200 }
201
202 hashed_service_t *hashed_service = hash_table_get_inst(link, hashed_service_t, link);
203 async_exch_t *exch = async_exchange_begin(hashed_service->sess);
204 async_forward_fast(callid, exch, iface, arg3, 0, IPC_FF_NONE);
205 async_exchange_end(exch);
206 return;
207
208out:
209 async_answer_0(callid, retval);
210}
211
212/**
213 * @}
214 */
Note: See TracBrowser for help on using the repository browser.