Changes in uspace/lib/c/generic/loc.c [cc574511:d0dd7b5] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/loc.c
rcc574511 rd0dd7b5 45 45 static FIBRIL_MUTEX_INITIALIZE(loc_consumer_mutex); 46 46 47 static FIBRIL_MUTEX_INITIALIZE(loc_callback_mutex); 48 static bool loc_callback_created = false; 49 47 50 static async_sess_t *loc_supp_block_sess = NULL; 48 51 static async_sess_t *loc_cons_block_sess = NULL; … … 51 54 static async_sess_t *loc_consumer_sess = NULL; 52 55 56 static loc_cat_change_cb_t cat_change_cb = NULL; 57 58 static void loc_cb_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg) 59 { 60 loc_cat_change_cb_t cb_fun; 61 62 while (true) { 63 ipc_call_t call; 64 ipc_callid_t callid = async_get_call(&call); 65 66 if (!IPC_GET_IMETHOD(call)) { 67 /* TODO: Handle hangup */ 68 return; 69 } 70 71 int retval; 72 73 switch (IPC_GET_IMETHOD(call)) { 74 case LOC_EVENT_CAT_CHANGE: 75 fibril_mutex_lock(&loc_callback_mutex); 76 cb_fun = cat_change_cb; 77 if (cb_fun != NULL) { 78 (*cb_fun)(); 79 } 80 fibril_mutex_unlock(&loc_callback_mutex); 81 retval = 0; 82 break; 83 default: 84 retval = ENOTSUP; 85 } 86 87 async_answer_0(callid, retval); 88 } 89 } 90 91 53 92 static void clone_session(fibril_mutex_t *mtx, async_sess_t *src, 54 93 async_sess_t **dst) … … 60 99 61 100 fibril_mutex_unlock(mtx); 101 } 102 103 static int loc_callback_create(void) 104 { 105 async_exch_t *exch; 106 sysarg_t retval; 107 int rc = EOK; 108 109 fibril_mutex_lock(&loc_callback_mutex); 110 111 if (!loc_callback_created) { 112 exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER); 113 114 ipc_call_t answer; 115 aid_t req = async_send_0(exch, LOC_CALLBACK_CREATE, &answer); 116 async_connect_to_me(exch, 0, 0, 0, loc_cb_conn, NULL); 117 loc_exchange_end(exch); 118 119 async_wait_for(req, &retval); 120 if (rc != EOK) 121 goto done; 122 123 if (retval != EOK) { 124 rc = retval; 125 goto done; 126 } 127 128 loc_callback_created = true; 129 } 130 131 rc = EOK; 132 done: 133 fibril_mutex_unlock(&loc_callback_mutex); 134 return rc; 62 135 } 63 136 … … 194 267 } 195 268 196 /** Register new device.197 * 198 * The @p interface is used when forwarding connection to the driver.269 /** Register new service. 270 * 271 * The @p interface is used when forwarding connection to the server. 199 272 * If not 0, the first argument is the interface and the second argument 200 273 * is the service ID. … … 203 276 * the handle (to ensure backward compatibility). 204 277 * 205 * @param fq dn Fully qualified device name.206 * @param[out] handle Handle to the created instance of device.207 * @param interface Interface when forwarding .208 * 209 */ 210 int loc_service_register_with_iface(const char *fq dn,211 service_id_t * handle, sysarg_t interface)278 * @param fqsn Fully qualified service name 279 * @param[out] sid Service ID of new service 280 * @param interface Interface when forwarding 281 * 282 */ 283 int loc_service_register_with_iface(const char *fqsn, 284 service_id_t *sid, sysarg_t interface) 212 285 { 213 286 async_exch_t *exch = loc_exchange_begin_blocking(LOC_PORT_SUPPLIER); … … 216 289 aid_t req = async_send_2(exch, LOC_SERVICE_REGISTER, interface, 0, 217 290 &answer); 218 sysarg_t retval = async_data_write_start(exch, fq dn, str_size(fqdn));291 sysarg_t retval = async_data_write_start(exch, fqsn, str_size(fqsn)); 219 292 220 293 loc_exchange_end(exch); … … 228 301 229 302 if (retval != EOK) { 230 if ( handle!= NULL)231 * handle= -1;232 233 return retval; 234 } 235 236 if ( handle!= NULL)237 * handle= (service_id_t) IPC_GET_ARG1(answer);303 if (sid != NULL) 304 *sid = -1; 305 306 return retval; 307 } 308 309 if (sid != NULL) 310 *sid = (service_id_t) IPC_GET_ARG1(answer); 238 311 239 312 return retval; 240 313 } 241 314 242 /** Register new device. 243 * 244 * @param fqdn Fully qualified device name. 245 * @param handle Output: Handle to the created instance of device. 246 * 247 */ 248 int loc_service_register(const char *fqdn, service_id_t *handle) 249 { 250 return loc_service_register_with_iface(fqdn, handle, 0); 315 /** Register new service. 316 * 317 * @param fqsn Fully qualified service name 318 * @param sid Output: ID of new service 319 * 320 */ 321 int loc_service_register(const char *fqdn, service_id_t *sid) 322 { 323 return loc_service_register_with_iface(fqdn, sid, 0); 324 } 325 326 /** Unregister service. 327 * 328 * @param sid Service ID 329 */ 330 int loc_service_unregister(service_id_t sid) 331 { 332 async_exch_t *exch; 333 sysarg_t retval; 334 335 exch = loc_exchange_begin_blocking(LOC_PORT_SUPPLIER); 336 retval = async_req_1_0(exch, LOC_SERVICE_UNREGISTER, sid); 337 loc_exchange_end(exch); 338 339 return (int)retval; 251 340 } 252 341 … … 289 378 290 379 return retval; 380 } 381 382 /** Get object name. 383 * 384 * Provided ID of an object, return its name. 385 * 386 * @param method IPC method 387 * @param id Object ID 388 * @param name Place to store pointer to new string. Caller should 389 * free it using free(). 390 * @return EOK on success or negative error code 391 */ 392 static int loc_get_name_internal(sysarg_t method, sysarg_t id, char **name) 393 { 394 async_exch_t *exch; 395 char name_buf[LOC_NAME_MAXLEN + 1]; 396 ipc_call_t dreply; 397 size_t act_size; 398 sysarg_t dretval; 399 400 *name = NULL; 401 exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER); 402 403 ipc_call_t answer; 404 aid_t req = async_send_1(exch, method, id, &answer); 405 aid_t dreq = async_data_read(exch, name_buf, LOC_NAME_MAXLEN, 406 &dreply); 407 async_wait_for(dreq, &dretval); 408 409 loc_exchange_end(exch); 410 411 if (dretval != EOK) { 412 async_wait_for(req, NULL); 413 return dretval; 414 } 415 416 sysarg_t retval; 417 async_wait_for(req, &retval); 418 419 if (retval != EOK) 420 return retval; 421 422 act_size = IPC_GET_ARG2(dreply); 423 assert(act_size <= LOC_NAME_MAXLEN); 424 name_buf[act_size] = '\0'; 425 426 *name = str_dup(name_buf); 427 if (*name == NULL) 428 return ENOMEM; 429 430 return EOK; 431 } 432 433 /** Get category name. 434 * 435 * Provided ID of a service, return its name. 436 * 437 * @param cat_id Category ID 438 * @param name Place to store pointer to new string. Caller should 439 * free it using free(). 440 * @return EOK on success or negative error code 441 */ 442 int loc_category_get_name(category_id_t cat_id, char **name) 443 { 444 return loc_get_name_internal(LOC_CATEGORY_GET_NAME, cat_id, name); 445 } 446 447 /** Get service name. 448 * 449 * Provided ID of a service, return its name. 450 * 451 * @param svc_id Service ID 452 * @param name Place to store pointer to new string. Caller should 453 * free it using free(). 454 * @return EOK on success or negative error code 455 */ 456 int loc_service_get_name(service_id_t svc_id, char **name) 457 { 458 return loc_get_name_internal(LOC_SERVICE_GET_NAME, svc_id, name); 291 459 } 292 460 … … 589 757 } 590 758 591 static int loc_category_get_ svcs_internal(category_id_t cat_id,592 s ervice_id_t *id_buf, size_t buf_size, size_t *act_size)759 static int loc_category_get_ids_once(sysarg_t method, sysarg_t arg1, 760 sysarg_t *id_buf, size_t buf_size, size_t *act_size) 593 761 { 594 762 async_exch_t *exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER); 595 763 596 764 ipc_call_t answer; 597 aid_t req = async_send_1(exch, LOC_CATEGORY_GET_SVCS, cat_id, 598 &answer); 765 aid_t req = async_send_1(exch, method, arg1, &answer); 599 766 int rc = async_data_read_start(exch, id_buf, buf_size); 600 767 … … 614 781 615 782 *act_size = IPC_GET_ARG1(answer); 783 return EOK; 784 } 785 786 /** Get list of IDs. 787 * 788 * Returns an allocated array of service IDs. 789 * 790 * @param method IPC method 791 * @param arg1 IPC argument 1 792 * @param data Place to store pointer to array of IDs 793 * @param count Place to store number of IDs 794 * @return EOK on success or negative error code 795 */ 796 static int loc_get_ids_internal(sysarg_t method, sysarg_t arg1, 797 sysarg_t **data, size_t *count) 798 { 799 service_id_t *ids; 800 size_t act_size; 801 size_t alloc_size; 802 int rc; 803 804 *data = NULL; 805 act_size = 0; /* silence warning */ 806 807 rc = loc_category_get_ids_once(method, arg1, NULL, 0, 808 &act_size); 809 if (rc != EOK) 810 return rc; 811 812 alloc_size = act_size; 813 ids = malloc(alloc_size); 814 if (ids == NULL) 815 return ENOMEM; 816 817 while (true) { 818 rc = loc_category_get_ids_once(method, arg1, ids, alloc_size, 819 &act_size); 820 if (rc != EOK) 821 return rc; 822 823 if (act_size <= alloc_size) 824 break; 825 826 alloc_size *= 2; 827 free(ids); 828 829 ids = malloc(alloc_size); 830 if (ids == NULL) 831 return ENOMEM; 832 } 833 834 *count = act_size / sizeof(category_id_t); 835 *data = ids; 616 836 return EOK; 617 837 } … … 626 846 * @return EOK on success or negative error code 627 847 */ 628 int loc_category_get_svcs(category_id_t cat_id, category_id_t **data,848 int loc_category_get_svcs(category_id_t cat_id, service_id_t **data, 629 849 size_t *count) 630 850 { 631 service_id_t *ids; 632 size_t act_size; 633 size_t alloc_size; 634 int rc; 635 636 *data = NULL; 637 act_size = 0; /* silence warning */ 638 639 rc = loc_category_get_svcs_internal(cat_id, NULL, 0, &act_size); 640 if (rc != EOK) 641 return rc; 642 643 alloc_size = act_size; 644 ids = malloc(alloc_size); 645 if (ids == NULL) 646 return ENOMEM; 647 648 while (true) { 649 rc = loc_category_get_svcs_internal(cat_id, ids, alloc_size, 650 &act_size); 651 if (rc != EOK) 652 return rc; 653 654 if (act_size <= alloc_size) 655 break; 656 657 alloc_size *= 2; 658 free(ids); 659 660 ids = malloc(alloc_size); 661 if (ids == NULL) 662 return ENOMEM; 663 } 664 665 *count = act_size / sizeof(category_id_t); 666 *data = ids; 851 return loc_get_ids_internal(LOC_CATEGORY_GET_SVCS, cat_id, 852 data, count); 853 } 854 855 /** Get list of categories. 856 * 857 * Returns an allocated array of category IDs. 858 * 859 * @param data Place to store pointer to array of IDs 860 * @param count Place to store number of IDs 861 * @return EOK on success or negative error code 862 */ 863 int loc_get_categories(category_id_t **data, size_t *count) 864 { 865 return loc_get_ids_internal(LOC_GET_CATEGORIES, 0, 866 data, count); 867 } 868 869 int loc_register_cat_change_cb(loc_cat_change_cb_t cb_fun) 870 { 871 if (loc_callback_create() != EOK) 872 return EIO; 873 874 cat_change_cb = cb_fun; 667 875 return EOK; 668 876 }
Note:
See TracChangeset
for help on using the changeset viewer.