Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 278ac72 in mainline


Ignore:
Timestamp:
2011-08-16T15:35:56Z (10 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master
Children:
30c78c0
Parents:
16dc887
Message:

Add API for getting list of categories.

Location:
uspace
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/loc.c

    r16dc887 r278ac72  
    589589}
    590590
    591 static int loc_category_get_svcs_internal(category_id_t cat_id,
    592     service_id_t *id_buf, size_t buf_size, size_t *act_size)
     591static int loc_category_get_ids_once(sysarg_t method, sysarg_t arg1,
     592    sysarg_t *id_buf, size_t buf_size, size_t *act_size)
    593593{
    594594        async_exch_t *exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER);
    595595
    596596        ipc_call_t answer;
    597         aid_t req = async_send_1(exch, LOC_CATEGORY_GET_SVCS, cat_id,
    598             &answer);
     597        aid_t req = async_send_1(exch, method, arg1, &answer);
    599598        int rc = async_data_read_start(exch, id_buf, buf_size);
    600599       
     
    614613       
    615614        *act_size = IPC_GET_ARG1(answer);
     615        return EOK;
     616}
     617
     618/** Get list of IDs.
     619 *
     620 * Returns an allocated array of service IDs.
     621 *
     622 * @param method        IPC method
     623 * @param arg1          IPC argument 1
     624 * @param data          Place to store pointer to array of IDs
     625 * @param count         Place to store number of IDs
     626 * @return              EOK on success or negative error code
     627 */
     628static int loc_get_ids_internal(sysarg_t method, sysarg_t arg1,
     629    sysarg_t **data, size_t *count)
     630{
     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_ids_once(method, arg1, NULL, 0,
     640            &act_size);
     641        if (rc != EOK)
     642                return rc;
     643
     644        alloc_size = act_size;
     645        ids = malloc(alloc_size);
     646        if (ids == NULL)
     647                return ENOMEM;
     648
     649        while (true) {
     650                rc = loc_category_get_ids_once(method, arg1, ids, alloc_size,
     651                    &act_size);
     652                if (rc != EOK)
     653                        return rc;
     654
     655                if (act_size <= alloc_size)
     656                        break;
     657
     658                alloc_size *= 2;
     659                free(ids);
     660
     661                ids = malloc(alloc_size);
     662                if (ids == NULL)
     663                        return ENOMEM;
     664        }
     665
     666        *count = act_size / sizeof(category_id_t);
     667        *data = ids;
    616668        return EOK;
    617669}
     
    626678 * @return              EOK on success or negative error code
    627679 */
    628 int loc_category_get_svcs(category_id_t cat_id, category_id_t **data,
     680int loc_category_get_svcs(category_id_t cat_id, service_id_t **data,
    629681    size_t *count)
    630682{
    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;
    667         return EOK;
    668 }
     683        return loc_get_ids_internal(LOC_CATEGORY_GET_SVCS, cat_id,
     684            data, count);
     685}
     686
     687/** Get list of categories.
     688 *
     689 * Returns an allocated array of category IDs.
     690 *
     691 * @param data          Place to store pointer to array of IDs
     692 * @param count         Place to store number of IDs
     693 * @return              EOK on success or negative error code
     694 */
     695int loc_get_categories(category_id_t **data, size_t *count)
     696{
     697        return loc_get_ids_internal(LOC_GET_CATEGORIES, 0,
     698            data, count);
     699}
  • uspace/lib/c/include/ipc/loc.h

    r16dc887 r278ac72  
    6363        LOC_GET_NAMESPACE_COUNT,
    6464        LOC_GET_SERVICE_COUNT,
     65        LOC_GET_CATEGORIES,
    6566        LOC_GET_NAMESPACES,
    6667        LOC_GET_SERVICES
  • uspace/lib/c/include/loc.h

    r16dc887 r278ac72  
    7070extern size_t loc_get_namespaces(loc_sdesc_t **);
    7171extern size_t loc_get_services(service_id_t, loc_sdesc_t **);
     72extern int loc_get_categories(category_id_t **, size_t *);
     73
    7274
    7375#endif
  • uspace/srv/loc/category.c

    r16dc887 r278ac72  
    5454        list_append(&cat->cat_list, &cdir->categories);
    5555}
     56
     57/** Get list of categories. */
     58int categ_dir_get_categories(categ_dir_t *cdir, category_id_t *id_buf,
     59    size_t buf_size, size_t *act_size)
     60{
     61        size_t act_cnt;
     62        size_t buf_cnt;
     63
     64        assert(fibril_mutex_is_locked(&cdir->mutex));
     65
     66        buf_cnt = buf_size / sizeof(category_id_t);
     67
     68        act_cnt = list_count(&cdir->categories);
     69        *act_size = act_cnt * sizeof(category_id_t);
     70
     71        if (buf_size % sizeof(category_id_t) != 0)
     72                return EINVAL;
     73
     74        size_t pos = 0;
     75        list_foreach(cdir->categories, item) {
     76                category_t *cat =
     77                    list_get_instance(item, category_t, cat_list);
     78
     79                if (pos < buf_cnt)
     80                        id_buf[pos] = cat->id;
     81                pos++;
     82        }
     83
     84        return EOK;
     85}
     86
    5687
    5788/** Initialize category structure. */
  • uspace/srv/loc/category.h

    r16dc887 r278ac72  
    6969extern void categ_dir_init(categ_dir_t *);
    7070extern void categ_dir_add_cat(categ_dir_t *, category_t *);
     71extern int categ_dir_get_categories(categ_dir_t *, service_id_t *, size_t,
     72    size_t *);
    7173extern category_t *category_new(const char *);
    7274extern int category_add_service(category_t *, loc_service_t *);
  • uspace/srv/loc/loc.c

    r16dc887 r278ac72  
    755755}
    756756
     757static void loc_get_categories(ipc_callid_t iid, ipc_call_t *icall)
     758{
     759        ipc_callid_t callid;
     760        size_t size;
     761        size_t act_size;
     762        int rc;
     763       
     764        if (!async_data_read_receive(&callid, &size)) {
     765                async_answer_0(callid, EREFUSED);
     766                async_answer_0(iid, EREFUSED);
     767                return;
     768        }
     769       
     770        category_id_t *id_buf = (category_id_t *) malloc(size);
     771        if (id_buf == NULL) {
     772                fibril_mutex_unlock(&cdir.mutex);
     773                async_answer_0(callid, ENOMEM);
     774                async_answer_0(iid, ENOMEM);
     775                return;
     776        }
     777       
     778        fibril_mutex_lock(&cdir.mutex);
     779       
     780        rc = categ_dir_get_categories(&cdir, id_buf, size, &act_size);
     781        if (rc != EOK) {
     782                fibril_mutex_unlock(&cdir.mutex);
     783                async_answer_0(callid, rc);
     784                async_answer_0(iid, rc);
     785                return;
     786        }
     787       
     788        fibril_mutex_unlock(&cdir.mutex);
     789       
     790        sysarg_t retval = async_data_read_finalize(callid, id_buf, size);
     791        free(id_buf);
     792       
     793        async_answer_1(iid, retval, act_size);
     794}
     795
    757796static void loc_get_namespaces(ipc_callid_t iid, ipc_call_t *icall)
    758797{
     
    11811220                case LOC_GET_SERVICE_COUNT:
    11821221                        loc_get_service_count(callid, &call);
     1222                        break;
     1223                case LOC_GET_CATEGORIES:
     1224                        loc_get_categories(callid, &call);
    11831225                        break;
    11841226                case LOC_GET_NAMESPACES:
Note: See TracChangeset for help on using the changeset viewer.