Changes in uspace/srv/loc/loc.c [cc574511:d0dd7b5] in mainline


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified uspace/srv/loc/loc.c

    rcc574511 rd0dd7b5  
    4444#include <bool.h>
    4545#include <fibril_synch.h>
     46#include <macros.h>
    4647#include <stdlib.h>
    4748#include <str.h>
     
    6667 **/
    6768
    68 static FIBRIL_MUTEX_INITIALIZE(services_list_mutex);
     69FIBRIL_MUTEX_INITIALIZE(services_list_mutex);
    6970static FIBRIL_CONDVAR_INITIALIZE(services_list_cv);
    7071static FIBRIL_MUTEX_INITIALIZE(servers_list_mutex);
     
    8384/** Service directory ogranized by categories (yellow pages) */
    8485static categ_dir_t cdir;
     86
     87static FIBRIL_MUTEX_INITIALIZE(callback_sess_mutex);
     88static async_sess_t *callback_sess = NULL;
    8589
    8690service_id_t loc_create_id(void)
     
    307311{
    308312        assert(fibril_mutex_is_locked(&services_list_mutex));
    309 
     313        assert(fibril_mutex_is_locked(&cdir.mutex));
     314       
    310315        loc_namespace_delref(service->namespace);
    311316        list_remove(&(service->services));
    312317        list_remove(&(service->server_services));
     318       
     319        /* Remove service from all categories. */
     320        while (!list_empty(&service->cat_memb)) {
     321                link_t *link = list_first(&service->cat_memb);
     322                svc_categ_t *memb = list_get_instance(link, svc_categ_t,
     323                    svc_link);
     324                fibril_mutex_lock(&memb->cat->mutex);
     325                category_remove_service(memb);
     326                fibril_mutex_unlock(&memb->cat->mutex);
     327        }
    313328       
    314329        free(service->name);
     
    411426        fibril_mutex_lock(&services_list_mutex);
    412427        fibril_mutex_lock(&server->services_mutex);
     428        fibril_mutex_lock(&cdir.mutex);
    413429       
    414430        while (!list_empty(&server->services)) {
     
    419435        }
    420436       
     437        fibril_mutex_unlock(&cdir.mutex);
    421438        fibril_mutex_unlock(&server->services_mutex);
    422439        fibril_mutex_unlock(&services_list_mutex);
     
    488505        link_initialize(&service->services);
    489506        link_initialize(&service->server_services);
     507        list_initialize(&service->cat_memb);
    490508       
    491509        /* Check that service is not already registered */
     
    525543 *
    526544 */
    527 static int loc_service_unregister(ipc_callid_t iid, ipc_call_t *icall,
     545static void loc_service_unregister(ipc_callid_t iid, ipc_call_t *icall,
    528546    loc_server_t *server)
    529547{
    530         /* TODO */
    531         return EOK;
     548        loc_service_t *svc;
     549       
     550        fibril_mutex_lock(&services_list_mutex);
     551        svc = loc_service_find_id(IPC_GET_ARG1(*icall));
     552        if (svc == NULL) {
     553                fibril_mutex_unlock(&services_list_mutex);
     554                async_answer_0(iid, ENOENT);
     555                return;
     556        }
     557       
     558        fibril_mutex_lock(&cdir.mutex);
     559        loc_service_unregister_core(svc);
     560        fibril_mutex_unlock(&cdir.mutex);
     561        fibril_mutex_unlock(&services_list_mutex);
     562        async_answer_0(iid, EOK);
     563}
     564
     565static void loc_category_get_name(ipc_callid_t iid, ipc_call_t *icall)
     566{
     567        ipc_callid_t callid;
     568        size_t size;
     569        size_t act_size;
     570        category_t *cat;
     571       
     572        if (!async_data_read_receive(&callid, &size)) {
     573                async_answer_0(callid, EREFUSED);
     574                async_answer_0(iid, EREFUSED);
     575                return;
     576        }
     577       
     578        fibril_mutex_lock(&cdir.mutex);
     579       
     580        cat = category_get(&cdir, IPC_GET_ARG1(*icall));
     581        if (cat == NULL) {
     582                fibril_mutex_unlock(&cdir.mutex);
     583                async_answer_0(callid, ENOENT);
     584                async_answer_0(iid, ENOENT);
     585                return;
     586        }
     587       
     588        act_size = str_size(cat->name);
     589        if (act_size > size) {
     590                fibril_mutex_unlock(&cdir.mutex);
     591                async_answer_0(callid, EOVERFLOW);
     592                async_answer_0(iid, EOVERFLOW);
     593                return;
     594        }
     595       
     596        sysarg_t retval = async_data_read_finalize(callid, cat->name,
     597            min(size, act_size));
     598       
     599        fibril_mutex_unlock(&cdir.mutex);
     600       
     601        async_answer_0(iid, retval);
     602}
     603
     604static void loc_service_get_name(ipc_callid_t iid, ipc_call_t *icall)
     605{
     606        ipc_callid_t callid;
     607        size_t size;
     608        size_t act_size;
     609        loc_service_t *svc;
     610       
     611        if (!async_data_read_receive(&callid, &size)) {
     612                async_answer_0(callid, EREFUSED);
     613                async_answer_0(iid, EREFUSED);
     614                return;
     615        }
     616       
     617        fibril_mutex_lock(&services_list_mutex);
     618       
     619        svc = loc_service_find_id(IPC_GET_ARG1(*icall));
     620        if (svc == NULL) {
     621                fibril_mutex_unlock(&services_list_mutex);
     622                async_answer_0(callid, ENOENT);
     623                async_answer_0(iid, ENOENT);
     624                return;
     625        }
     626       
     627        act_size = str_size(svc->name);
     628        if (act_size > size) {
     629                fibril_mutex_unlock(&services_list_mutex);
     630                async_answer_0(callid, EOVERFLOW);
     631                async_answer_0(iid, EOVERFLOW);
     632                return;
     633        }
     634       
     635        sysarg_t retval = async_data_read_finalize(callid, svc->name,
     636            min(size, act_size));
     637       
     638        fibril_mutex_unlock(&services_list_mutex);
     639       
     640        async_answer_0(iid, retval);
    532641}
    533642
     
    687796 *
    688797 */
     798static void loc_callback_create(ipc_callid_t iid, ipc_call_t *icall)
     799{
     800        async_sess_t *cb_sess = async_callback_receive(EXCHANGE_SERIALIZE);
     801        if (cb_sess == NULL) {
     802                async_answer_0(iid, ENOMEM);
     803                return;
     804        }
     805       
     806        fibril_mutex_lock(&callback_sess_mutex);
     807        if (callback_sess != NULL) {
     808                fibril_mutex_unlock(&callback_sess_mutex);
     809                async_answer_0(iid, EEXIST);
     810                return;
     811        }
     812       
     813        callback_sess = cb_sess;
     814        fibril_mutex_unlock(&callback_sess_mutex);
     815       
     816        async_answer_0(iid, EOK);
     817}
     818
     819void loc_category_change_event(void)
     820{
     821        fibril_mutex_lock(&callback_sess_mutex);
     822
     823        if (callback_sess != NULL) {
     824                async_exch_t *exch = async_exchange_begin(callback_sess);
     825                async_msg_0(exch, LOC_EVENT_CAT_CHANGE);
     826                async_exchange_end(exch);
     827        }
     828
     829        fibril_mutex_unlock(&callback_sess_mutex);
     830}
     831
     832/** Find ID for category specified by name.
     833 *
     834 * On success, answer will contain EOK int retval and service ID in arg1.
     835 * On failure, error code will be sent in retval.
     836 *
     837 */
    689838static void loc_category_get_id(ipc_callid_t iid, ipc_call_t *icall)
    690839{
     
    755904}
    756905
     906static void loc_get_categories(ipc_callid_t iid, ipc_call_t *icall)
     907{
     908        ipc_callid_t callid;
     909        size_t size;
     910        size_t act_size;
     911        int rc;
     912       
     913        if (!async_data_read_receive(&callid, &size)) {
     914                async_answer_0(callid, EREFUSED);
     915                async_answer_0(iid, EREFUSED);
     916                return;
     917        }
     918       
     919        category_id_t *id_buf = (category_id_t *) malloc(size);
     920        if (id_buf == NULL) {
     921                fibril_mutex_unlock(&cdir.mutex);
     922                async_answer_0(callid, ENOMEM);
     923                async_answer_0(iid, ENOMEM);
     924                return;
     925        }
     926       
     927        fibril_mutex_lock(&cdir.mutex);
     928       
     929        rc = categ_dir_get_categories(&cdir, id_buf, size, &act_size);
     930        if (rc != EOK) {
     931                fibril_mutex_unlock(&cdir.mutex);
     932                async_answer_0(callid, rc);
     933                async_answer_0(iid, rc);
     934                return;
     935        }
     936       
     937        fibril_mutex_unlock(&cdir.mutex);
     938       
     939        sysarg_t retval = async_data_read_finalize(callid, id_buf, size);
     940        free(id_buf);
     941       
     942        async_answer_1(iid, retval, act_size);
     943}
     944
    757945static void loc_get_namespaces(ipc_callid_t iid, ipc_call_t *icall)
    758946{
     
    10151203       
    10161204        fibril_mutex_lock(&services_list_mutex);
     1205        fibril_mutex_lock(&cdir.mutex);
    10171206        loc_service_unregister_core(null_services[i]);
     1207        fibril_mutex_unlock(&cdir.mutex);
    10181208        fibril_mutex_unlock(&services_list_mutex);
    10191209       
     
    10491239
    10501240        async_answer_0(iid, retval);
     1241
     1242        loc_category_change_event();
    10511243}
    10521244
     
    10761268
    10771269        cat = category_new("serial");
     1270        categ_dir_add_cat(&cdir, cat);
     1271
     1272        cat = category_new("usbhc");
     1273        categ_dir_add_cat(&cdir, cat);
     1274
     1275        cat = category_new("virtual");
    10781276        categ_dir_add_cat(&cdir, cat);
    10791277
     
    11581356                        loc_service_get_id(callid, &call);
    11591357                        break;
     1358                case LOC_SERVICE_GET_NAME:
     1359                        loc_service_get_name(callid, &call);
     1360                        break;
    11601361                case LOC_NAMESPACE_GET_ID:
    11611362                        loc_namespace_get_id(callid, &call);
    11621363                        break;
     1364                case LOC_CALLBACK_CREATE:
     1365                        loc_callback_create(callid, &call);
     1366                        break;
    11631367                case LOC_CATEGORY_GET_ID:
    11641368                        loc_category_get_id(callid, &call);
    11651369                        break;
     1370                case LOC_CATEGORY_GET_NAME:
     1371                        loc_category_get_name(callid, &call);
     1372                        break;
    11661373                case LOC_CATEGORY_GET_SVCS:
    11671374                        loc_category_get_svcs(callid, &call);
     
    11811388                case LOC_GET_SERVICE_COUNT:
    11821389                        loc_get_service_count(callid, &call);
     1390                        break;
     1391                case LOC_GET_CATEGORIES:
     1392                        loc_get_categories(callid, &call);
    11831393                        break;
    11841394                case LOC_GET_NAMESPACES:
Note: See TracChangeset for help on using the changeset viewer.