Changes in uspace/lib/c/generic/async/ports.c [cb20b05:0db0df2] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async/ports.c
rcb20b05 r0db0df2 1 1 /* 2 * Copyright (c) 2025 Jiri Svoboda3 2 * Copyright (c) 2006 Ondrej Palkovsky 4 3 * All rights reserved. … … 60 59 iface_t iface; 61 60 62 /** Interface connection handler*/63 async_port_handler_t handler;64 65 /** Client data*/66 void *data;61 /** Interface ports */ 62 hash_table_t port_hash_table; 63 64 /** Next available port ID */ 65 port_id_t port_id_avail; 67 66 } interface_t; 68 67 … … 74 73 port_id_t id; 75 74 76 /** Port interfaces */ 77 hash_table_t interface_hash_table; 75 /** Port connection handler */ 76 async_port_handler_t handler; 77 78 /** Client data */ 79 void *data; 78 80 } port_t; 79 81 … … 96 98 static void *fallback_port_data = NULL; 97 99 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; 100 /** Futex guarding the interface hash table. */ 101 static fibril_rmutex_t interface_mutex; 102 static hash_table_t interface_hash_table; 103 103 104 104 static size_t interface_key_hash(const void *key) … … 158 158 }; 159 159 160 static interface_t *async_new_interface(port_t *port, iface_t iface, 161 async_port_handler_t handler, void *data) 160 static interface_t *async_new_interface(iface_t iface) 162 161 { 163 162 interface_t *interface = … … 165 164 if (!interface) 166 165 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 167 174 interface->iface = iface; 168 interface->handler = handler; 169 interface->data = data; 170 171 hash_table_insert(&port->interface_hash_table, &interface->link); 175 interface->port_id_avail = 0; 176 177 hash_table_insert(&interface_hash_table, &interface->link); 172 178 173 179 return interface; 174 180 } 175 181 176 static port_t *async_new_port(void) 182 static port_t *async_new_port(interface_t *interface, 183 async_port_handler_t handler, void *data) 177 184 { 178 185 // TODO: Move the malloc out of critical section. … … 181 188 return NULL; 182 189 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++; 190 port_id_t id = interface->port_id_avail; 191 interface->port_id_avail++; 192 192 193 193 port->id = id; 194 hash_table_insert(&port_hash_table, &port->link); 194 port->handler = handler; 195 port->data = data; 196 197 hash_table_insert(&interface->port_hash_table, &port->link); 195 198 196 199 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);214 200 } 215 201 … … 219 205 interface_t *interface; 220 206 221 fibril_rmutex_lock(&port_mutex); 222 223 port_t *port = async_new_port(); 224 if (port == NULL) { 225 fibril_rmutex_unlock(&port_mutex); 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); 226 217 return ENOMEM; 227 218 } 228 219 229 interface = async_new_interface(port, iface, handler, data); 230 if (interface == NULL) { 231 async_delete_port(port); 232 fibril_rmutex_unlock(&port_mutex); 220 port_t *port = async_new_port(interface, handler, data); 221 if (!port) { 222 fibril_rmutex_unlock(&interface_mutex); 233 223 return ENOMEM; 234 224 } 235 225 236 226 *port_id = port->id; 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); 227 228 fibril_rmutex_unlock(&interface_mutex); 229 260 230 return EOK; 261 231 } … … 278 248 } 279 249 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) 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) 332 273 { 333 274 assert(data); … … 336 277 *data = fallback_port_data; 337 278 338 interface_t *interface = async_find_interface(iface, port_id);339 if ( interface != NULL) {340 handler = interface->handler;341 *data = interface->data;279 port_t *port = async_find_port(iface, port_id); 280 if (port) { 281 handler = port->handler; 282 *data = port->data; 342 283 } 343 284 … … 345 286 } 346 287 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. 288 /** Initialize the async framework. 361 289 * 362 290 */ 363 291 void __async_ports_init(void) 364 292 { 365 if (fibril_rmutex_initialize(& port_mutex) != EOK)293 if (fibril_rmutex_initialize(&interface_mutex) != EOK) 366 294 abort(); 367 295 368 if (!hash_table_create(&port_hash_table, 0, 0, &port_hash_table_ops)) 296 if (!hash_table_create(&interface_hash_table, 0, 0, 297 &interface_hash_table_ops)) 369 298 abort(); 370 299 } … … 372 301 void __async_ports_fini(void) 373 302 { 374 fibril_rmutex_destroy(& port_mutex);375 } 303 fibril_rmutex_destroy(&interface_mutex); 304 }
Note:
See TracChangeset
for help on using the changeset viewer.