Changeset f0cc1c64 in mainline for uspace/lib/c/generic/async/ports.c
- Timestamp:
- 2025-06-20T19:26:13Z (3 days ago)
- Children:
- 817cb83
- Parents:
- f0360ec (diff), 5caad1d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async/ports.c
rf0360ec rf0cc1c64 1 1 /* 2 * Copyright (c) 2025 Jiri Svoboda 2 3 * Copyright (c) 2006 Ondrej Palkovsky 3 4 * All rights reserved. … … 59 60 iface_t iface; 60 61 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; 66 67 } interface_t; 67 68 … … 73 74 port_id_t id; 74 75 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; 80 78 } port_t; 81 79 … … 98 96 static void *fallback_port_data = NULL; 99 97 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. */ 99 static fibril_rmutex_t port_mutex; 100 static hash_table_t port_hash_table; 101 /** Next available port ID */ 102 static port_id_t port_id_avail = 0; 103 103 104 104 static size_t interface_key_hash(const void *key) … … 158 158 }; 159 159 160 static interface_t *async_new_interface(iface_t iface) 160 static interface_t *async_new_interface(port_t *port, iface_t iface, 161 async_port_handler_t handler, void *data) 161 162 { 162 163 interface_t *interface = … … 164 165 if (!interface) 165 166 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 174 167 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); 178 172 179 173 return interface; 180 174 } 181 175 182 static port_t *async_new_port(interface_t *interface, 183 async_port_handler_t handler, void *data) 176 static port_t *async_new_port(void) 184 177 { 185 178 // TODO: Move the malloc out of critical section. … … 188 181 return NULL; 189 182 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++; 192 192 193 193 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); 198 195 199 196 return port; 197 } 198 199 static bool destroy_if(ht_link_t *link, void *arg) 200 { 201 port_t *port = (port_t *)arg; 202 203 hash_table_remove_item(&port->interface_hash_table, link); 204 return false; 205 } 206 207 static void async_delete_port(port_t *port) 208 { 209 /* Destroy interfaces */ 210 hash_table_apply(&port->interface_hash_table, destroy_if, port); 211 212 hash_table_destroy(&port->interface_hash_table); 213 free(port); 200 214 } 201 215 … … 205 219 interface_t *interface; 206 220 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); 221 fibril_rmutex_lock(&port_mutex); 222 223 port_t *port = async_new_port(); 224 if (port == NULL) { 225 fibril_rmutex_unlock(&port_mutex); 217 226 return ENOMEM; 218 227 } 219 228 220 port_t *port = async_new_port(interface, handler, data); 221 if (!port) { 222 fibril_rmutex_unlock(&interface_mutex); 229 interface = async_new_interface(port, iface, handler, data); 230 if (interface == NULL) { 231 async_delete_port(port); 232 fibril_rmutex_unlock(&port_mutex); 223 233 return ENOMEM; 224 234 } 225 235 226 236 *port_id = port->id; 227 228 fibril_rmutex_unlock(&interface_mutex); 229 237 fibril_rmutex_unlock(&port_mutex); 238 return EOK; 239 } 240 241 errno_t async_port_create_interface(port_id_t port_id, iface_t iface, 242 async_port_handler_t handler, void *data) 243 { 244 ht_link_t *link; 245 port_t *port; 246 interface_t *interface; 247 248 fibril_rmutex_lock(&port_mutex); 249 link = hash_table_find(&port_hash_table, &port_id); 250 assert(link != NULL); 251 port = hash_table_get_inst(link, port_t, link); 252 253 interface = async_new_interface(port, iface, handler, data); 254 if (interface == NULL) { 255 fibril_rmutex_unlock(&port_mutex); 256 return ENOMEM; 257 } 258 259 fibril_rmutex_unlock(&port_mutex); 230 260 return EOK; 231 261 } … … 248 278 } 249 279 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) 280 typedef struct { 281 iface_t iface; 282 interface_t *interface; 283 } find_if_port_t; 284 285 static bool find_if_port(ht_link_t *link, void *arg) 286 { 287 find_if_port_t *fip = (find_if_port_t *)arg; 288 port_t *port; 289 interface_t *interface; 290 291 (void)arg; 292 port = hash_table_get_inst(link, port_t, link); 293 294 ht_link_t *ilink = hash_table_find(&port->interface_hash_table, 295 &fip->iface); 296 if (ilink) { 297 interface = hash_table_get_inst(ilink, interface_t, 298 link); 299 fip->interface = interface; 300 return false; 301 } 302 303 return true; 304 } 305 306 static interface_t *async_find_interface(iface_t iface, port_id_t port_id) 307 { 308 interface_t *interface = NULL; 309 find_if_port_t fip; 310 311 (void)port_id; // XXX !!! 312 313 fibril_rmutex_lock(&port_mutex); 314 315 /* 316 * XXX Find any port implementing that interface. In reality we should 317 * only look at port with ID port_id - but server.c does not 318 * provide us with a correct port ID 319 */ 320 321 fip.iface = iface; 322 fip.interface = NULL; 323 hash_table_apply(&port_hash_table, find_if_port, (void *)&fip); 324 interface = fip.interface; 325 326 fibril_rmutex_unlock(&port_mutex); 327 return interface; 328 } 329 330 async_port_handler_t async_get_interface_handler(iface_t iface, 331 port_id_t port_id, void **data) 273 332 { 274 333 assert(data); … … 277 336 *data = fallback_port_data; 278 337 279 port_t *port = async_find_port(iface, port_id);280 if ( port) {281 handler = port->handler;282 *data = port->data;338 interface_t *interface = async_find_interface(iface, port_id); 339 if (interface != NULL) { 340 handler = interface->handler; 341 *data = interface->data; 283 342 } 284 343 … … 286 345 } 287 346 288 /** Initialize the async framework. 347 void async_port_destroy(port_id_t port_id) 348 { 349 ht_link_t *link; 350 port_t *port; 351 352 fibril_rmutex_lock(&port_mutex); 353 link = hash_table_find(&port_hash_table, &port_id); 354 assert(link != NULL); 355 port = hash_table_get_inst(link, port_t, link); 356 async_delete_port(port); 357 fibril_rmutex_unlock(&port_mutex); 358 } 359 360 /** Initialize the async framework ports. 289 361 * 290 362 */ 291 363 void __async_ports_init(void) 292 364 { 293 if (fibril_rmutex_initialize(& interface_mutex) != EOK)365 if (fibril_rmutex_initialize(&port_mutex) != EOK) 294 366 abort(); 295 367 296 if (!hash_table_create(&interface_hash_table, 0, 0, 297 &interface_hash_table_ops)) 368 if (!hash_table_create(&port_hash_table, 0, 0, &port_hash_table_ops)) 298 369 abort(); 299 370 } … … 301 372 void __async_ports_fini(void) 302 373 { 303 fibril_rmutex_destroy(& interface_mutex);304 } 374 fibril_rmutex_destroy(&port_mutex); 375 }
Note:
See TracChangeset
for help on using the changeset viewer.