Changeset 3951046 in mainline


Ignore:
Timestamp:
2025-06-16T19:32:56Z (16 hours ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Parents:
5c55eb7
Message:

Async ports and interfaces do the castling.

Now interfaces hang under ports.
Minimum change, missing port ID to select port if iface type is the
same.

Location:
uspace/lib/c/generic
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/async/ports.c

    r5c55eb7 r3951046  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2006 Ondrej Palkovsky
    34 * All rights reserved.
     
    5960        iface_t iface;
    6061
    61         /** Interface ports */
    62         hash_table_t port_hash_table;
    63 
    64         /** Next available port ID */
    65         port_id_t port_id_avail;
     62        /** Interface connection handler */
     63        async_port_handler_t handler;
     64
     65        /** Client data */
     66        void *data;
    6667} interface_t;
    6768
     
    7374        port_id_t id;
    7475
    75         /** Port connection handler */
    76         async_port_handler_t handler;
    77 
    78         /** Client data */
    79         void *data;
     76        /** Port interfaces */
     77        hash_table_t interface_hash_table;
    8078} port_t;
    8179
     
    9896static void *fallback_port_data = NULL;
    9997
    100 /** Futex guarding the interface hash table. */
    101 static fibril_rmutex_t interface_mutex;
    102 static hash_table_t interface_hash_table;
     98/** Futex guarding the port hash table. */
     99static fibril_rmutex_t port_mutex;
     100static hash_table_t port_hash_table;
     101/** Next available port ID */
     102static port_id_t port_id_avail = 0;
    103103
    104104static size_t interface_key_hash(const void *key)
     
    158158};
    159159
    160 static interface_t *async_new_interface(iface_t iface)
     160static interface_t *async_new_interface(port_t *port, iface_t iface,
     161    async_port_handler_t handler, void *data)
    161162{
    162163        interface_t *interface =
     
    164165        if (!interface)
    165166                return NULL;
    166 
    167         bool ret = hash_table_create(&interface->port_hash_table, 0, 0,
    168             &port_hash_table_ops);
    169         if (!ret) {
    170                 free(interface);
    171                 return NULL;
    172         }
    173 
    174167        interface->iface = iface;
    175         interface->port_id_avail = 0;
    176 
    177         hash_table_insert(&interface_hash_table, &interface->link);
     168        interface->handler = handler;
     169        interface->data = data;
     170
     171        hash_table_insert(&port->interface_hash_table, &interface->link);
    178172
    179173        return interface;
    180174}
    181175
    182 static port_t *async_new_port(interface_t *interface,
    183     async_port_handler_t handler, void *data)
     176static port_t *async_new_port(void)
    184177{
    185178        // TODO: Move the malloc out of critical section.
     
    188181                return NULL;
    189182
    190         port_id_t id = interface->port_id_avail;
    191         interface->port_id_avail++;
     183        bool ret = hash_table_create(&port->interface_hash_table, 0, 0,
     184            &interface_hash_table_ops);
     185        if (!ret) {
     186                free(port);
     187                return NULL;
     188        }
     189
     190        port_id_t id = port_id_avail;
     191        port_id_avail++;
    192192
    193193        port->id = id;
    194         port->handler = handler;
    195         port->data = data;
    196 
    197         hash_table_insert(&interface->port_hash_table, &port->link);
     194        hash_table_insert(&port_hash_table, &port->link);
    198195
    199196        return port;
     
    205202        interface_t *interface;
    206203
    207         fibril_rmutex_lock(&interface_mutex);
    208 
    209         ht_link_t *link = hash_table_find(&interface_hash_table, &iface);
    210         if (link)
    211                 interface = hash_table_get_inst(link, interface_t, link);
    212         else
    213                 interface = async_new_interface(iface);
    214 
    215         if (!interface) {
    216                 fibril_rmutex_unlock(&interface_mutex);
     204        fibril_rmutex_lock(&port_mutex);
     205
     206        port_t *port = async_new_port();
     207        if (port == NULL) {
     208                fibril_rmutex_unlock(&port_mutex);
    217209                return ENOMEM;
    218210        }
    219211
    220         port_t *port = async_new_port(interface, handler, data);
    221         if (!port) {
    222                 fibril_rmutex_unlock(&interface_mutex);
     212        interface = async_new_interface(port, iface, handler, data);
     213        if (interface == NULL) {
     214                // XXX delete port
     215                fibril_rmutex_unlock(&port_mutex);
    223216                return ENOMEM;
    224217        }
    225218
    226219        *port_id = port->id;
    227 
    228         fibril_rmutex_unlock(&interface_mutex);
    229 
     220        fibril_rmutex_unlock(&port_mutex);
    230221        return EOK;
    231222}
     
    248239}
    249240
    250 static port_t *async_find_port(iface_t iface, port_id_t port_id)
    251 {
    252         port_t *port = NULL;
    253 
    254         fibril_rmutex_lock(&interface_mutex);
    255 
    256         ht_link_t *link = hash_table_find(&interface_hash_table, &iface);
    257         if (link) {
    258                 interface_t *interface =
    259                     hash_table_get_inst(link, interface_t, link);
    260 
    261                 link = hash_table_find(&interface->port_hash_table, &port_id);
    262                 if (link)
    263                         port = hash_table_get_inst(link, port_t, link);
    264         }
    265 
    266         fibril_rmutex_unlock(&interface_mutex);
    267 
    268         return port;
    269 }
    270 
    271 async_port_handler_t async_get_port_handler(iface_t iface, port_id_t port_id,
    272     void **data)
     241typedef struct {
     242        iface_t iface;
     243        interface_t *interface;
     244} find_if_port_t;
     245
     246static bool find_if_port(ht_link_t *link, void *arg)
     247{
     248        find_if_port_t *fip = (find_if_port_t *)arg;
     249        port_t *port;
     250        interface_t *interface;
     251
     252        (void)arg;
     253        port = hash_table_get_inst(link, port_t, link);
     254
     255        ht_link_t *ilink = hash_table_find(&port->interface_hash_table,
     256            &fip->iface);
     257        if (ilink) {
     258                interface = hash_table_get_inst(ilink, interface_t,
     259                    link);
     260                fip->interface = interface;
     261                return false;
     262        }
     263
     264        return true;
     265}
     266
     267static interface_t *async_find_interface(iface_t iface, port_id_t port_id)
     268{
     269        interface_t *interface = NULL;
     270        find_if_port_t fip;
     271
     272        (void)port_id; // XXX !!!
     273
     274        fibril_rmutex_lock(&port_mutex);
     275
     276        /*
     277         * XXX Find any port implementing that interface. In reality we should
     278         * only look at port with ID port_id - but server.c does not
     279         * provide us with a correct port ID
     280         */
     281
     282        fip.iface = iface;
     283        fip.interface = NULL;
     284        hash_table_apply(&port_hash_table, find_if_port, (void *)&fip);
     285        interface = fip.interface;
     286
     287        fibril_rmutex_unlock(&port_mutex);
     288        return interface;
     289}
     290
     291async_port_handler_t async_get_interface_handler(iface_t iface,
     292    port_id_t port_id, void **data)
    273293{
    274294        assert(data);
     
    277297        *data = fallback_port_data;
    278298
    279         port_t *port = async_find_port(iface, port_id);
    280         if (port) {
    281                 handler = port->handler;
    282                 *data = port->data;
     299        interface_t *interface = async_find_interface(iface, port_id);
     300        if (interface != NULL) {
     301                handler = interface->handler;
     302                *data = interface->data;
    283303        }
    284304
     
    286306}
    287307
    288 /** Initialize the async framework.
     308/** Initialize the async framework ports.
    289309 *
    290310 */
    291311void __async_ports_init(void)
    292312{
    293         if (fibril_rmutex_initialize(&interface_mutex) != EOK)
     313        if (fibril_rmutex_initialize(&port_mutex) != EOK)
    294314                abort();
    295315
    296         if (!hash_table_create(&interface_hash_table, 0, 0,
    297             &interface_hash_table_ops))
     316        if (!hash_table_create(&port_hash_table, 0, 0, &port_hash_table_ops))
    298317                abort();
    299318}
     
    301320void __async_ports_fini(void)
    302321{
    303         fibril_rmutex_destroy(&interface_mutex);
    304 }
     322        fibril_rmutex_destroy(&port_mutex);
     323}
  • uspace/lib/c/generic/async/server.c

    r5c55eb7 r3951046  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2006 Ondrej Palkovsky
    34 * All rights reserved.
     
    955956                void *data;
    956957                async_port_handler_t handler =
    957                     async_get_port_handler(iface, 0, &data);
     958                    async_get_interface_handler(iface, 0, &data);
    958959
    959960                async_new_connection(conn, call->task_id, call, handler, data);
  • uspace/lib/c/generic/private/async.h

    r5c55eb7 r3951046  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2006 Ondrej Palkovsky
    34 * All rights reserved.
     
    103104extern errno_t async_create_port_internal(iface_t, async_port_handler_t,
    104105    void *, port_id_t *);
    105 extern async_port_handler_t async_get_port_handler(iface_t, port_id_t, void **);
     106extern async_port_handler_t async_get_interface_handler(iface_t, port_id_t,
     107    void **);
    106108
    107109extern void async_reply_received(ipc_call_t *);
Note: See TracChangeset for help on using the changeset viewer.