Changeset 9b1baac in mainline


Ignore:
Timestamp:
2018-07-18T08:35:42Z (6 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0b05082
Parents:
edc64c0
Message:

ns: register service interfaces individually

Each service interface is now registered individually with the naming
service. This adds a degree of type safety, potentially allows the
individual interfaces to be implemented by independent tasks and moves
the code slightly closer to the full-fledged ports design.

Broker services (e.g. the location service) can still register a
fallback port for receiving connections to all interface types
explicitly using service_register_broker().

Files:
19 edited

Legend:

Unmodified
Added
Removed
  • abi/include/abi/ipc/interfaces.h

    redc64c0 r9b1baac  
    7979
    8080typedef enum {
     81        INTERFACE_ANY = 0,
    8182        INTERFACE_LOADER =
    8283            FOURCC_COMPACT('l', 'o', 'a', 'd') | IFACE_EXCHANGE_SERIALIZE,
  • uspace/lib/c/generic/async/server.c

    redc64c0 r9b1baac  
    13171317 * Ask through phone for a new connection to some service.
    13181318 *
    1319  * @param exch Exchange for sending the message.
    1320  * @param arg1 User defined argument.
    1321  * @param arg2 User defined argument.
    1322  * @param arg3 User defined argument.
     1319 * @param exch  Exchange for sending the message.
     1320 * @param iface Callback interface.
     1321 * @param arg2  User defined argument.
     1322 * @param arg3  User defined argument.
    13231323 *
    13241324 * @return Zero on success or an error code.
    13251325 *
    13261326 */
    1327 errno_t async_connect_to_me(async_exch_t *exch, sysarg_t arg1, sysarg_t arg2,
     1327errno_t async_connect_to_me(async_exch_t *exch, iface_t iface, sysarg_t arg2,
    13281328    sysarg_t arg3)
    13291329{
     
    13321332
    13331333        ipc_call_t answer;
    1334         aid_t req = async_send_3(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
     1334        aid_t req = async_send_3(exch, IPC_M_CONNECT_TO_ME, iface, arg2, arg3,
    13351335            &answer);
    13361336
  • uspace/lib/c/generic/devman.c

    redc64c0 r9b1baac  
    192192
    193193        exch = devman_exchange_begin(INTERFACE_DDF_DRIVER);
    194         async_connect_to_me(exch, 0, 0, 0);
     194        async_connect_to_me(exch, INTERFACE_ANY, 0, 0);
    195195        devman_exchange_end(exch);
    196196
  • uspace/lib/c/generic/loc.c

    redc64c0 r9b1baac  
    255255        }
    256256
    257         async_connect_to_me(exch, 0, 0, 0);
     257        async_connect_to_me(exch, INTERFACE_ANY, 0, 0);
    258258
    259259        /*
  • uspace/lib/c/generic/ns.c

    redc64c0 r9b1baac  
    4646static async_sess_t *sess_ns = NULL;
    4747
    48 errno_t service_register(service_t service)
    49 {
    50         errno_t retval;
     48errno_t service_register(service_t service, iface_t iface,
     49    async_port_handler_t handler, void *data)
     50{
     51        async_sess_t *sess = ns_session_get();
     52        if (sess == NULL)
     53                return EIO;
     54
     55        port_id_t port;
     56        errno_t rc = async_create_port(iface, handler, data, &port);
     57        if (rc != EOK)
     58                return rc;
     59
     60        async_exch_t *exch = async_exchange_begin(sess);
     61
    5162        ipc_call_t answer;
    52 
    53         async_sess_t *sess = ns_session_get();
    54         if (sess == NULL)
    55                 return EIO;
    56 
    57         async_exch_t *exch = async_exchange_begin(sess);
    58         aid_t req = async_send_1(exch, NS_REGISTER, service, &answer);
    59         errno_t rc = async_connect_to_me(exch, 0, service, 0);
     63        aid_t req = async_send_2(exch, NS_REGISTER, service, iface, &answer);
     64        rc = async_connect_to_me(exch, iface, service, 0);
    6065
    6166        async_exchange_end(exch);
     
    6671        }
    6772
     73        errno_t retval;
     74        async_wait_for(req, &retval);
     75        return rc;
     76}
     77
     78errno_t service_register_broker(service_t service, async_port_handler_t handler,
     79    void *data)
     80{
     81        async_set_fallback_port_handler(handler, data);
     82
     83        async_sess_t *sess = ns_session_get();
     84        if (sess == NULL)
     85                return EIO;
     86
     87        async_exch_t *exch = async_exchange_begin(sess);
     88
     89        ipc_call_t answer;
     90        aid_t req = async_send_1(exch, NS_REGISTER_BROKER, service, &answer);
     91        errno_t rc = async_connect_to_me(exch, INTERFACE_ANY, service, 0);
     92
     93        async_exchange_end(exch);
     94
     95        if (rc != EOK) {
     96                async_forget(req);
     97                return rc;
     98        }
     99
     100        errno_t retval;
    68101        async_wait_for(req, &retval);
    69102        return rc;
  • uspace/lib/c/include/async.h

    redc64c0 r9b1baac  
    342342extern async_sess_t *async_connect_kbox(task_id_t);
    343343
    344 extern errno_t async_connect_to_me(async_exch_t *, sysarg_t, sysarg_t, sysarg_t);
     344extern errno_t async_connect_to_me(async_exch_t *, iface_t, sysarg_t, sysarg_t);
    345345
    346346extern errno_t async_hangup(async_sess_t *);
  • uspace/lib/c/include/ipc/ns.h

    redc64c0 r9b1baac  
    4141        NS_PING = IPC_FIRST_USER_METHOD,
    4242        NS_REGISTER,
     43        NS_REGISTER_BROKER,
    4344        NS_TASK_WAIT,
    4445        NS_ID_INTRO,
  • uspace/lib/c/include/ns.h

    redc64c0 r9b1baac  
    4040#include <async.h>
    4141
    42 extern errno_t service_register(service_t);
     42extern errno_t service_register(service_t, iface_t, async_port_handler_t,
     43    void *);
     44extern errno_t service_register_broker(service_t, async_port_handler_t, void *);
    4345extern async_sess_t *service_connect(service_t, iface_t, sysarg_t);
    4446extern async_sess_t *service_connect_blocking(service_t, iface_t, sysarg_t);
  • uspace/srv/devman/main.c

    redc64c0 r9b1baac  
    325325        async_set_client_data_destructor(devman_client_data_destroy);
    326326
    327         port_id_t port;
    328         rc = async_create_port(INTERFACE_DDF_DRIVER,
    329             devman_connection_driver, NULL, &port);
    330         if (rc != EOK) {
    331                 printf("%s: Error creating DDF driver port: %s\n", NAME, str_error(rc));
    332                 return rc;
    333         }
    334 
    335         rc = async_create_port(INTERFACE_DDF_CLIENT,
    336             devman_connection_client, NULL, &port);
    337         if (rc != EOK) {
    338                 printf("%s: Error creating DDF client port: %s\n", NAME, str_error(rc));
    339                 return rc;
    340         }
    341 
    342         rc = async_create_port(INTERFACE_DEVMAN_DEVICE,
    343             devman_connection_device, NULL, &port);
    344         if (rc != EOK) {
    345                 printf("%s: Error creating devman device port: %s\n", NAME, str_error(rc));
    346                 return rc;
    347         }
    348 
    349         rc = async_create_port(INTERFACE_DEVMAN_PARENT,
    350             devman_connection_parent, NULL, &port);
    351         if (rc != EOK) {
    352                 printf("%s: Error creating devman parent port: %s\n", NAME, str_error(rc));
    353                 return rc;
    354         }
    355 
    356327        async_set_fallback_port_handler(devman_forward, NULL);
    357328
     
    362333
    363334        /* Register device manager at naming service. */
    364         rc = service_register(SERVICE_DEVMAN);
    365         if (rc != EOK) {
    366                 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering as a service: %s", str_error(rc));
     335        rc = service_register(SERVICE_DEVMAN, INTERFACE_DDF_DRIVER,
     336            devman_connection_driver, NULL);
     337        if (rc != EOK) {
     338                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering driver port: %s", str_error(rc));
     339                return rc;
     340        }
     341
     342        rc = service_register(SERVICE_DEVMAN, INTERFACE_DDF_CLIENT,
     343            devman_connection_client, NULL);
     344        if (rc != EOK) {
     345                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering client port: %s", str_error(rc));
     346                return rc;
     347        }
     348
     349        rc = service_register(SERVICE_DEVMAN, INTERFACE_DEVMAN_DEVICE,
     350            devman_connection_device, NULL);
     351        if (rc != EOK) {
     352                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering device port: %s", str_error(rc));
     353                return rc;
     354        }
     355
     356        rc = service_register(SERVICE_DEVMAN, INTERFACE_DEVMAN_PARENT,
     357            devman_connection_parent, NULL);
     358        if (rc != EOK) {
     359                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering parent port: %s", str_error(rc));
    367360                return rc;
    368361        }
  • uspace/srv/loader/main.c

    redc64c0 r9b1baac  
    399399int main(int argc, char *argv[])
    400400{
    401         async_set_fallback_port_handler(ldr_connection, NULL);
    402 
    403401        /* Introduce this task to the NS (give it our task ID). */
    404402        task_id_t id = task_get_id();
     
    407405                return rc;
    408406
    409         /* Create port */
    410         port_id_t port;
    411         rc = async_create_port(INTERFACE_LOADER, ldr_connection, NULL, &port);
     407        /* Register at naming service. */
     408        rc = service_register(SERVICE_LOADER, INTERFACE_LOADER,
     409            ldr_connection, NULL);
    412410        if (rc != EOK)
    413411                return rc;
    414412
    415         /* Register at naming service. */
    416         rc = service_register(SERVICE_LOADER);
    417         if (rc != EOK)
    418                 return rc;
    419 
    420413        async_manager();
    421414
  • uspace/srv/locsrv/locsrv.c

    redc64c0 r9b1baac  
    15331533        }
    15341534
    1535         port_id_t port;
    1536         errno_t rc = async_create_port(INTERFACE_LOC_SUPPLIER,
    1537             loc_connection_supplier, NULL, &port);
     1535        /* Register location service at naming service */
     1536        errno_t rc = service_register(SERVICE_LOC, INTERFACE_LOC_SUPPLIER,
     1537            loc_connection_supplier, NULL);
    15381538        if (rc != EOK) {
    1539                 printf("%s: Error while creating supplier port: %s\n", NAME, str_error(rc));
     1539                printf("%s: Error while registering supplier service: %s\n", NAME, str_error(rc));
    15401540                return rc;
    15411541        }
    15421542
    1543         rc = async_create_port(INTERFACE_LOC_CONSUMER,
    1544             loc_connection_consumer, NULL, &port);
     1543        rc = service_register(SERVICE_LOC, INTERFACE_LOC_CONSUMER,
     1544            loc_connection_consumer, NULL);
    15451545        if (rc != EOK) {
    1546                 printf("%s: Error while creating consumer port: %s\n", NAME, str_error(rc));
     1546                printf("%s: Error while registering consumer service: %s\n", NAME, str_error(rc));
    15471547                return rc;
    15481548        }
    15491549
    1550         /* Set a handler of incomming connections */
    1551         async_set_fallback_port_handler(loc_forward, NULL);
    1552 
    1553         /* Register location service at naming service */
    1554         rc = service_register(SERVICE_LOC);
     1550        rc = service_register_broker(SERVICE_LOC, loc_forward, NULL);
    15551551        if (rc != EOK) {
    1556                 printf("%s: Error while registering service: %s\n", NAME, str_error(rc));
     1552                printf("%s: Error while registering broker service: %s\n", NAME, str_error(rc));
    15571553                return rc;
    15581554        }
  • uspace/srv/logger/main.c

    redc64c0 r9b1baac  
    6767        }
    6868
    69         port_id_t port;
    70         errno_t rc = async_create_port(INTERFACE_LOGGER_CONTROL,
    71             connection_handler_control, NULL, &port);
     69        errno_t rc = service_register(SERVICE_LOGGER, INTERFACE_LOGGER_CONTROL,
     70            connection_handler_control, NULL);
    7271        if (rc != EOK) {
    73                 printf("%s: Error while creating control port: %s\n", NAME, str_error(rc));
    74                 return rc;
    75         }
    76 
    77         rc = async_create_port(INTERFACE_LOGGER_WRITER,
    78             connection_handler_writer, NULL, &port);
    79         if (rc != EOK) {
    80                 printf("%s: Error while creating writer port: %s\n", NAME, str_error(rc));
    81                 return rc;
    82         }
    83 
    84         rc = service_register(SERVICE_LOGGER);
    85         if (rc != EOK) {
    86                 printf(NAME ": failed to register: %s.\n", str_error(rc));
     72                printf("%s: Failed to register control port: %s.\n", NAME,
     73                    str_error(rc));
    8774                return -1;
    8875        }
    8976
    90         printf(NAME ": Accepting connections\n");
     77        rc = service_register(SERVICE_LOGGER, INTERFACE_LOGGER_WRITER,
     78            connection_handler_writer, NULL);
     79        if (rc != EOK) {
     80                printf("%s: Failed to register writer port: %s.\n", NAME,
     81                    str_error(rc));
     82                return -1;
     83        }
     84
     85        printf("%s: Accepting connections\n", NAME);
    9186        async_manager();
    9287
  • uspace/srv/ns/clonable.c

    redc64c0 r9b1baac  
    5454static list_t cs_req;
    5555
    56 errno_t clonable_init(void)
     56errno_t ns_clonable_init(void)
    5757{
    5858        list_initialize(&cs_req);
     
    6161
    6262/** Return true if @a service is clonable. */
    63 bool service_clonable(service_t service)
     63bool ns_service_is_clonable(service_t service, iface_t iface)
    6464{
    65         return (service == SERVICE_LOADER);
     65        return (service == SERVICE_LOADER) && (iface == INTERFACE_LOADER);
    6666}
    6767
    6868/** Register clonable service.
    6969 *
    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.
    7371 *
    7472 */
    75 void register_clonable(service_t service, sysarg_t phone, ipc_call_t *call)
     73void ns_clonable_register(ipc_call_t *call)
    7674{
    7775        link_t *req_link = list_first(&cs_req);
     
    8785
    8886        /* 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));
    9088
    9189        async_answer_0(call, EOK);
     
    113111 *
    114112 */
    115 void connect_to_clonable(service_t service, iface_t iface, ipc_call_t *call)
     113void ns_clonable_forward(service_t service, iface_t iface, ipc_call_t *call)
    116114{
    117         assert(service == SERVICE_LOADER);
     115        assert(ns_service_is_clonable(service, iface));
    118116
    119117        cs_req_t *csr = malloc(sizeof(cs_req_t));
  • uspace/srv/ns/clonable.h

    redc64c0 r9b1baac  
    3939#include <stdbool.h>
    4040
    41 extern errno_t clonable_init(void);
     41extern errno_t ns_clonable_init(void);
    4242
    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 *);
     43extern bool ns_service_is_clonable(service_t, iface_t);
     44extern void ns_clonable_register(ipc_call_t *);
     45extern void ns_clonable_forward(service_t, iface_t, ipc_call_t *);
    4646
    4747#endif
  • uspace/srv/ns/ns.c

    redc64c0 r9b1baac  
    6161                 * Client requests to be connected to a service.
    6262                 */
    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);
    6565                } else {
    66                         connect_to_service(service, iface, icall);
     66                        ns_service_forward(service, iface, icall);
    6767                }
     68
    6869                return;
    6970        }
     
    7273
    7374        while (true) {
    74                 process_pending_conn();
     75                ns_pending_conn_process();
    7576
    7677                async_get_call(&call);
     
    8283
    8384                service_t service;
    84                 sysarg_t phone;
    8585
    8686                switch (IPC_GET_IMETHOD(call)) {
    8787                case NS_REGISTER:
    8888                        service = IPC_GET_ARG1(call);
    89                         phone = IPC_GET_ARG5(call);
     89                        iface = IPC_GET_ARG2(call);
    9090
    9191                        /*
    9292                         * Server requests service registration.
    9393                         */
    94                         if (service_clonable(service)) {
    95                                 register_clonable(service, phone, &call);
     94                        if (ns_service_is_clonable(service, iface)) {
     95                                ns_clonable_register(&call);
    9696                                continue;
    9797                        } else {
    98                                 retval = register_service(service, phone, &call);
     98                                retval = ns_service_register(service, iface);
    9999                        }
    100100
     101                        break;
     102                case NS_REGISTER_BROKER:
     103                        service = IPC_GET_ARG1(call);
     104                        retval = ns_service_register_broker(service);
    101105                        break;
    102106                case NS_PING:
     
    115119                        break;
    116120                default:
    117                         printf("ns: method not supported\n");
     121                        printf("%s: Method not supported (%" PRIun ")\n",
     122                            NAME, IPC_GET_IMETHOD(call));
    118123                        retval = ENOTSUP;
    119124                        break;
     
    130135        printf("%s: HelenOS IPC Naming Service\n", NAME);
    131136
    132         errno_t rc = service_init();
     137        errno_t rc = ns_service_init();
    133138        if (rc != EOK)
    134139                return rc;
    135140
    136         rc = clonable_init();
     141        rc = ns_clonable_init();
    137142        if (rc != EOK)
    138143                return rc;
  • uspace/srv/ns/service.c

    redc64c0 r9b1baac  
    4747        service_t service;
    4848
     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. */
     57typedef struct {
     58        ht_link_t link;
     59
     60        /** Interface ID */
     61        iface_t iface;
     62
    4963        /** Session to the service */
    5064        async_sess_t *sess;
    51 } hashed_service_t;
     65} hashed_iface_t;
    5266
    5367static size_t service_key_hash(void *key)
     
    7084
    7185        return service->service == *(service_t *) key;
     86}
     87
     88static size_t iface_key_hash(void *key)
     89{
     90        return *(iface_t *) key;
     91}
     92
     93static 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
     101static 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;
    72107}
    73108
     
    81116};
    82117
     118/** Operations for interface hash table. */
     119static 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
    83127/** Service hash table structure. */
    84128static hash_table_t service_hash_table;
     
    94138static list_t pending_conn;
    95139
    96 errno_t service_init(void)
     140errno_t ns_service_init(void)
    97141{
    98142        if (!hash_table_create(&service_hash_table, 0, 0,
     
    107151}
    108152
     153static 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
    109161/** Process pending connection requests */
    110 void process_pending_conn(void)
     162void ns_pending_conn_process(void)
    111163{
    112164loop:
    113165        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);
    115168                if (!link)
    116169                        continue;
    117170
    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);
    123194
    124195                list_remove(&pending->link);
     
    129200}
    130201
     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 */
     210static 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 */
     241static 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
    131253/** Register service.
    132254 *
    133255 * @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.
    136257 *
    137258 * @return Zero on success or a value from @ref errno.h.
    138259 *
    139260 */
    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;
     261errno_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        }
    144273
    145274        hashed_service_t *hashed_service =
     
    148277                return ENOMEM;
    149278
     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;
    150286        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        }
    154292
    155293        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 */
     304errno_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 */
     341static 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);
    156355        return EOK;
    157356}
     
    166365 *
    167366 */
    168 void connect_to_service(service_t service, iface_t iface, ipc_call_t *call)
     367void ns_service_forward(service_t service, iface_t iface, ipc_call_t *call)
    169368{
    170369        sysarg_t flags = IPC_GET_ARG4(*call);
     
    175374                if (flags & IPC_FLAG_BLOCKING) {
    176375                        /* 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);
    190395                        return;
    191396                }
    192397
     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
    193408                retval = ENOENT;
    194409                goto out;
    195410        }
    196411
    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);
    201416        return;
    202417
  • uspace/srv/ns/service.h

    redc64c0 r9b1baac  
    3838#include <abi/ipc/interfaces.h>
    3939
    40 extern errno_t service_init(void);
    41 extern void process_pending_conn(void);
     40extern errno_t ns_service_init(void);
     41extern void ns_pending_conn_process(void);
    4242
    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 *);
     43extern errno_t ns_service_register(service_t, iface_t);
     44extern errno_t ns_service_register_broker(service_t);
     45extern void ns_service_forward(service_t, iface_t, ipc_call_t *);
    4546
    4647#endif
  • uspace/srv/vfs/vfs.c

    redc64c0 r9b1baac  
    117117
    118118        /*
    119          * Create a port for the pager.
    120          */
    121         port_id_t port;
    122         errno_t rc = async_create_port(INTERFACE_PAGER, vfs_pager, NULL, &port);
    123         if (rc != EOK) {
    124                 printf("%s: Cannot create pager port: %s\n", NAME, str_error(rc));
    125                 return rc;
    126         }
    127 
    128         /*
    129          * Set a connection handling function/fibril.
    130          */
    131         async_set_fallback_port_handler(vfs_connection, NULL);
    132 
    133         /*
    134119         * Subscribe to notifications.
    135120         */
     
    140125         * Register at the naming service.
    141126         */
    142         rc = service_register(SERVICE_VFS);
     127        errno_t rc = service_register(SERVICE_VFS, INTERFACE_PAGER, vfs_pager, NULL);
    143128        if (rc != EOK) {
    144                 printf("%s: Cannot register VFS service: %s\n", NAME, str_error(rc));
     129                printf("%s: Cannot register VFS pager port: %s\n", NAME, str_error(rc));
     130                return rc;
     131        }
     132
     133        rc = service_register(SERVICE_VFS, INTERFACE_VFS, vfs_connection, NULL);
     134        if (rc != EOK) {
     135                printf("%s: Cannot register VFS file system port: %s\n", NAME, str_error(rc));
     136                return rc;
     137        }
     138
     139        rc = service_register(SERVICE_VFS, INTERFACE_VFS_DRIVER, vfs_connection, NULL);
     140        if (rc != EOK) {
     141                printf("%s: Cannot register VFS driver port: %s\n", NAME, str_error(rc));
    145142                return rc;
    146143        }
  • uspace/srv/vfs/vfs_register.c

    redc64c0 r9b1baac  
    187187        }
    188188
     189        /* FIXME: Work around problem with callback sessions */
     190        async_sess_args_set(fs_info->sess, INTERFACE_VFS_DRIVER_CB, 0, 0);
     191
    189192        dprintf("Callback connection to FS created.\n");
    190193
Note: See TracChangeset for help on using the changeset viewer.