Changeset 9b1baac in mainline for uspace/srv/ns
- 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
- Location:
- uspace/srv/ns
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/ns/clonable.c
redc64c0 r9b1baac 54 54 static list_t cs_req; 55 55 56 errno_t clonable_init(void)56 errno_t ns_clonable_init(void) 57 57 { 58 58 list_initialize(&cs_req); … … 61 61 62 62 /** Return true if @a service is clonable. */ 63 bool service_clonable(service_t service)63 bool ns_service_is_clonable(service_t service, iface_t iface) 64 64 { 65 return (service == SERVICE_LOADER) ;65 return (service == SERVICE_LOADER) && (iface == INTERFACE_LOADER); 66 66 } 67 67 68 68 /** Register clonable service. 69 69 * 70 * @param service Service to be registered. 71 * @param phone Phone to be used for connections to the service. 72 * @param call Pointer to call structure. 70 * @param call Pointer to call structure. 73 71 * 74 72 */ 75 void register_clonable(service_t service, sysarg_t phone,ipc_call_t *call)73 void ns_clonable_register(ipc_call_t *call) 76 74 { 77 75 link_t *req_link = list_first(&cs_req); … … 87 85 88 86 /* Currently we can only handle a single type of clonable service. */ 89 assert( csr->service == SERVICE_LOADER);87 assert(ns_service_is_clonable(csr->service, csr->iface)); 90 88 91 89 async_answer_0(call, EOK); … … 113 111 * 114 112 */ 115 void connect_to_clonable(service_t service, iface_t iface, ipc_call_t *call)113 void ns_clonable_forward(service_t service, iface_t iface, ipc_call_t *call) 116 114 { 117 assert( service == SERVICE_LOADER);115 assert(ns_service_is_clonable(service, iface)); 118 116 119 117 cs_req_t *csr = malloc(sizeof(cs_req_t)); -
uspace/srv/ns/clonable.h
redc64c0 r9b1baac 39 39 #include <stdbool.h> 40 40 41 extern errno_t clonable_init(void);41 extern errno_t ns_clonable_init(void); 42 42 43 extern bool service_clonable(service_t);44 extern void register_clonable(service_t, sysarg_t,ipc_call_t *);45 extern void connect_to_clonable(service_t, iface_t, ipc_call_t *);43 extern bool ns_service_is_clonable(service_t, iface_t); 44 extern void ns_clonable_register(ipc_call_t *); 45 extern void ns_clonable_forward(service_t, iface_t, ipc_call_t *); 46 46 47 47 #endif -
uspace/srv/ns/ns.c
redc64c0 r9b1baac 61 61 * Client requests to be connected to a service. 62 62 */ 63 if ( service_clonable(service)) {64 connect_to_clonable(service, iface, icall);63 if (ns_service_is_clonable(service, iface)) { 64 ns_clonable_forward(service, iface, icall); 65 65 } else { 66 connect_to_service(service, iface, icall);66 ns_service_forward(service, iface, icall); 67 67 } 68 68 69 return; 69 70 } … … 72 73 73 74 while (true) { 74 process_pending_conn();75 ns_pending_conn_process(); 75 76 76 77 async_get_call(&call); … … 82 83 83 84 service_t service; 84 sysarg_t phone;85 85 86 86 switch (IPC_GET_IMETHOD(call)) { 87 87 case NS_REGISTER: 88 88 service = IPC_GET_ARG1(call); 89 phone = IPC_GET_ARG5(call);89 iface = IPC_GET_ARG2(call); 90 90 91 91 /* 92 92 * Server requests service registration. 93 93 */ 94 if ( service_clonable(service)) {95 register_clonable(service, phone,&call);94 if (ns_service_is_clonable(service, iface)) { 95 ns_clonable_register(&call); 96 96 continue; 97 97 } else { 98 retval = register_service(service, phone, &call);98 retval = ns_service_register(service, iface); 99 99 } 100 100 101 break; 102 case NS_REGISTER_BROKER: 103 service = IPC_GET_ARG1(call); 104 retval = ns_service_register_broker(service); 101 105 break; 102 106 case NS_PING: … … 115 119 break; 116 120 default: 117 printf("ns: method not supported\n"); 121 printf("%s: Method not supported (%" PRIun ")\n", 122 NAME, IPC_GET_IMETHOD(call)); 118 123 retval = ENOTSUP; 119 124 break; … … 130 135 printf("%s: HelenOS IPC Naming Service\n", NAME); 131 136 132 errno_t rc = service_init();137 errno_t rc = ns_service_init(); 133 138 if (rc != EOK) 134 139 return rc; 135 140 136 rc = clonable_init();141 rc = ns_clonable_init(); 137 142 if (rc != EOK) 138 143 return rc; -
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 -
uspace/srv/ns/service.h
redc64c0 r9b1baac 38 38 #include <abi/ipc/interfaces.h> 39 39 40 extern errno_t service_init(void);41 extern void process_pending_conn(void);40 extern errno_t ns_service_init(void); 41 extern void ns_pending_conn_process(void); 42 42 43 extern errno_t register_service(service_t, sysarg_t, ipc_call_t *); 44 extern void connect_to_service(service_t, iface_t, ipc_call_t *); 43 extern errno_t ns_service_register(service_t, iface_t); 44 extern errno_t ns_service_register_broker(service_t); 45 extern void ns_service_forward(service_t, iface_t, ipc_call_t *); 45 46 46 47 #endif
Note:
See TracChangeset
for help on using the changeset viewer.