Changeset 9b1baac in mainline for uspace/srv/ns/service.c
- Timestamp:
- 2018-07-18T08:35:42Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0b05082
- Parents:
- edc64c0
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/ns/service.c
redc64c0 r9b1baac 47 47 service_t service; 48 48 49 /** Interface hash table */ 50 hash_table_t iface_hash_table; 51 52 /** Broker session to the service */ 53 async_sess_t *broker_sess; 54 } hashed_service_t; 55 56 /** Interface hash table item. */ 57 typedef struct { 58 ht_link_t link; 59 60 /** Interface ID */ 61 iface_t iface; 62 49 63 /** Session to the service */ 50 64 async_sess_t *sess; 51 } hashed_ service_t;65 } hashed_iface_t; 52 66 53 67 static size_t service_key_hash(void *key) … … 70 84 71 85 return service->service == *(service_t *) key; 86 } 87 88 static size_t iface_key_hash(void *key) 89 { 90 return *(iface_t *) key; 91 } 92 93 static size_t iface_hash(const ht_link_t *item) 94 { 95 hashed_iface_t *iface = 96 hash_table_get_inst(item, hashed_iface_t, link); 97 98 return iface->iface; 99 } 100 101 static bool iface_key_equal(void *key, const ht_link_t *item) 102 { 103 hashed_iface_t *iface = 104 hash_table_get_inst(item, hashed_iface_t, link); 105 106 return iface->iface == *(iface_t *) key; 72 107 } 73 108 … … 81 116 }; 82 117 118 /** Operations for interface hash table. */ 119 static hash_table_ops_t iface_hash_table_ops = { 120 .hash = iface_hash, 121 .key_hash = iface_key_hash, 122 .key_equal = iface_key_equal, 123 .equal = NULL, 124 .remove_callback = NULL 125 }; 126 83 127 /** Service hash table structure. */ 84 128 static hash_table_t service_hash_table; … … 94 138 static list_t pending_conn; 95 139 96 errno_t service_init(void)140 errno_t ns_service_init(void) 97 141 { 98 142 if (!hash_table_create(&service_hash_table, 0, 0, … … 107 151 } 108 152 153 static void ns_forward(async_sess_t *sess, ipc_call_t *call, iface_t iface) 154 { 155 async_exch_t *exch = async_exchange_begin(sess); 156 async_forward_fast(call, exch, iface, IPC_GET_ARG3(*call), 0, 157 IPC_FF_NONE); 158 async_exchange_end(exch); 159 } 160 109 161 /** Process pending connection requests */ 110 void process_pending_conn(void)162 void ns_pending_conn_process(void) 111 163 { 112 164 loop: 113 165 list_foreach(pending_conn, link, pending_conn_t, pending) { 114 ht_link_t *link = hash_table_find(&service_hash_table, &pending->service); 166 ht_link_t *link = 167 hash_table_find(&service_hash_table, &pending->service); 115 168 if (!link) 116 169 continue; 117 170 118 hashed_service_t *hashed_service = hash_table_get_inst(link, hashed_service_t, link); 119 async_exch_t *exch = async_exchange_begin(hashed_service->sess); 120 async_forward_fast(&pending->call, exch, pending->iface, 121 IPC_GET_ARG3(pending->call), 0, IPC_FF_NONE); 122 async_exchange_end(exch); 171 hashed_service_t *hashed_service = 172 hash_table_get_inst(link, hashed_service_t, link); 173 174 link = hash_table_find(&hashed_service->iface_hash_table, 175 &pending->iface); 176 if (!link) { 177 if (hashed_service->broker_sess != NULL) { 178 ns_forward(hashed_service->broker_sess, &pending->call, 179 pending->iface); 180 181 list_remove(&pending->link); 182 free(pending); 183 184 goto loop; 185 } 186 187 continue; 188 } 189 190 hashed_iface_t *hashed_iface = 191 hash_table_get_inst(link, hashed_iface_t, link); 192 193 ns_forward(hashed_iface->sess, &pending->call, pending->iface); 123 194 124 195 list_remove(&pending->link); … … 129 200 } 130 201 202 /** Register interface to a service. 203 * 204 * @param service Service to which the interface belongs. 205 * @param iface Interface to be registered. 206 * 207 * @return Zero on success or a value from @ref errno.h. 208 * 209 */ 210 static errno_t ns_iface_register(hashed_service_t *hashed_service, iface_t iface) 211 { 212 ht_link_t *link = hash_table_find(&hashed_service->iface_hash_table, 213 &iface); 214 if (link) 215 return EEXIST; 216 217 hashed_iface_t *hashed_iface = 218 (hashed_iface_t *) malloc(sizeof(hashed_iface_t)); 219 if (!hashed_iface) 220 return ENOMEM; 221 222 hashed_iface->iface = iface; 223 hashed_iface->sess = async_callback_receive(EXCHANGE_SERIALIZE); 224 if (hashed_iface->sess == NULL) { 225 free(hashed_iface); 226 return EIO; 227 } 228 229 hash_table_insert(&hashed_service->iface_hash_table, 230 &hashed_iface->link); 231 return EOK; 232 } 233 234 /** Register broker to a service. 235 * 236 * @param service Service to which the broker belongs. 237 * 238 * @return Zero on success or a value from @ref errno.h. 239 * 240 */ 241 static errno_t ns_broker_register(hashed_service_t *hashed_service) 242 { 243 if (hashed_service->broker_sess != NULL) 244 return EEXIST; 245 246 hashed_service->broker_sess = async_callback_receive(EXCHANGE_SERIALIZE); 247 if (hashed_service->broker_sess == NULL) 248 return EIO; 249 250 return EOK; 251 } 252 131 253 /** Register service. 132 254 * 133 255 * @param service Service to be registered. 134 * @param phone Phone to be used for connections to the service. 135 * @param call Pointer to call structure. 256 * @param iface Interface to be registered. 136 257 * 137 258 * @return Zero on success or a value from @ref errno.h. 138 259 * 139 260 */ 140 errno_t register_service(service_t service, sysarg_t phone, ipc_call_t *call) 141 { 142 if (hash_table_find(&service_hash_table, &service)) 143 return EEXIST; 261 errno_t ns_service_register(service_t service, iface_t iface) 262 { 263 ht_link_t *link = hash_table_find(&service_hash_table, &service); 264 265 if (link) { 266 hashed_service_t *hashed_service = 267 hash_table_get_inst(link, hashed_service_t, link); 268 269 assert(hashed_service->service == service); 270 271 return ns_iface_register(hashed_service, iface); 272 } 144 273 145 274 hashed_service_t *hashed_service = … … 148 277 return ENOMEM; 149 278 279 if (!hash_table_create(&hashed_service->iface_hash_table, 0, 0, 280 &iface_hash_table_ops)) { 281 free(hashed_service); 282 return ENOMEM; 283 } 284 285 hashed_service->broker_sess = NULL; 150 286 hashed_service->service = service; 151 hashed_service->sess = async_callback_receive(EXCHANGE_SERIALIZE); 152 if (hashed_service->sess == NULL) 153 return EIO; 287 errno_t rc = ns_iface_register(hashed_service, iface); 288 if (rc != EOK) { 289 free(hashed_service); 290 return rc; 291 } 154 292 155 293 hash_table_insert(&service_hash_table, &hashed_service->link); 294 return EOK; 295 } 296 297 /** Register broker service. 298 * 299 * @param service Broker service to be registered. 300 * 301 * @return Zero on success or a value from @ref errno.h. 302 * 303 */ 304 errno_t ns_service_register_broker(service_t service) 305 { 306 ht_link_t *link = hash_table_find(&service_hash_table, &service); 307 308 if (link) { 309 hashed_service_t *hashed_service = 310 hash_table_get_inst(link, hashed_service_t, link); 311 312 assert(hashed_service->service == service); 313 314 return ns_broker_register(hashed_service); 315 } 316 317 hashed_service_t *hashed_service = 318 (hashed_service_t *) malloc(sizeof(hashed_service_t)); 319 if (!hashed_service) 320 return ENOMEM; 321 322 if (!hash_table_create(&hashed_service->iface_hash_table, 0, 0, 323 &iface_hash_table_ops)) { 324 free(hashed_service); 325 return ENOMEM; 326 } 327 328 hashed_service->broker_sess = NULL; 329 hashed_service->service = service; 330 errno_t rc = ns_broker_register(hashed_service); 331 if (rc != EOK) { 332 free(hashed_service); 333 return rc; 334 } 335 336 hash_table_insert(&service_hash_table, &hashed_service->link); 337 return EOK; 338 } 339 340 /** Add pending connection */ 341 static errno_t ns_pending_conn_add(service_t service, iface_t iface, 342 ipc_call_t *call) 343 { 344 pending_conn_t *pending = 345 (pending_conn_t *) malloc(sizeof(pending_conn_t)); 346 if (!pending) 347 return ENOMEM; 348 349 link_initialize(&pending->link); 350 pending->service = service; 351 pending->iface = iface; 352 pending->call = *call; 353 354 list_append(&pending->link, &pending_conn); 156 355 return EOK; 157 356 } … … 166 365 * 167 366 */ 168 void connect_to_service(service_t service, iface_t iface, ipc_call_t *call)367 void ns_service_forward(service_t service, iface_t iface, ipc_call_t *call) 169 368 { 170 369 sysarg_t flags = IPC_GET_ARG4(*call); … … 175 374 if (flags & IPC_FLAG_BLOCKING) { 176 375 /* Blocking connection, add to pending list */ 177 pending_conn_t *pending = 178 (pending_conn_t *) malloc(sizeof(pending_conn_t)); 179 if (!pending) { 180 retval = ENOMEM; 181 goto out; 182 } 183 184 link_initialize(&pending->link); 185 pending->service = service; 186 pending->iface = iface; 187 pending->call = *call; 188 189 list_append(&pending->link, &pending_conn); 376 errno_t rc = ns_pending_conn_add(service, iface, call); 377 if (rc == EOK) 378 return; 379 380 retval = rc; 381 goto out; 382 } 383 384 retval = ENOENT; 385 goto out; 386 } 387 388 hashed_service_t *hashed_service = 389 hash_table_get_inst(link, hashed_service_t, link); 390 391 link = hash_table_find(&hashed_service->iface_hash_table, &iface); 392 if (!link) { 393 if (hashed_service->broker_sess != NULL) { 394 ns_forward(hashed_service->broker_sess, call, iface); 190 395 return; 191 396 } 192 397 398 if (flags & IPC_FLAG_BLOCKING) { 399 /* Blocking connection, add to pending list */ 400 errno_t rc = ns_pending_conn_add(service, iface, call); 401 if (rc == EOK) 402 return; 403 404 retval = rc; 405 goto out; 406 } 407 193 408 retval = ENOENT; 194 409 goto out; 195 410 } 196 411 197 hashed_ service_t *hashed_service = hash_table_get_inst(link, hashed_service_t, link);198 async_exch_t *exch = async_exchange_begin(hashed_service->sess);199 async_forward_fast(call, exch, iface, IPC_GET_ARG3(*call), 0, IPC_FF_NONE); 200 async_exchange_end(exch);412 hashed_iface_t *hashed_iface = 413 hash_table_get_inst(link, hashed_iface_t, link); 414 415 ns_forward(hashed_iface->sess, call, iface); 201 416 return; 202 417
Note:
See TracChangeset
for help on using the changeset viewer.